Python 动态规划难题:寻找3个(不同)块的最长连续对

Python 动态规划难题:寻找3个(不同)块的最长连续对,python,recursion,dynamic-programming,memoization,Python,Recursion,Dynamic Programming,Memoization,谜题: 我的做法: 一套三件。 需要找出最长的连续集合,以便集合中的所有片段都不相同。 然后从巧克力棒的总长度中减去这个 从索引1开始(基于0) 分 案例1:如果相同,不要考虑当前索引。 从下一个索引中查找 如果条[current-1]==条[current]和条[current]==条[current+1]: 如果dp[电流+1]=-1: dp[current+1]=countContinuitiveSets(current+1) dp[电流]=dp[电流+1] 返回dp[当前] 案例2:

谜题:

我的做法:

一套三件。
需要找出最长的连续集合,以便集合中的所有片段都不相同。
然后从巧克力棒的总长度中减去这个

从索引1开始(基于0)

案例1:如果相同,不要考虑当前索引。 从下一个索引中查找

如果条[current-1]==条[current]和条[current]==条[current+1]:
如果dp[电流+1]=-1:
dp[current+1]=countContinuitiveSets(current+1)
dp[电流]=dp[电流+1]
返回dp[当前]

案例2:如果零件不同
案例2.1:考虑当前集合:为当前集合计算1,查找当前集之后的剩余集合计数。
如果dp[当前+3]=-1:
dp[当前+3]=countcontinuevesets(当前+3)
电流=1+dp[电流+3]
案例2.2:忽略当前集合:从下一个当前集合中查找剩余集合

如果dp[当前+1]=-1:
dp[current+1]=countContinuitiveSets(current+1)
无电流=dp[电流+1]
由于必须找到最大连续集,请查找
max(案例2.1和案例2.2)


基本情况: 当当前处于最后一个索引(或大于最后一个索引)时,无法形成集合。
所以返回0



完整代码
def CountRemainingCandies(self,bar):
dp=[-1]*(长(巴)+2)
def计数器连续设置(当前):
#解决小的子问题
如果电流>=len(bar)-1:
dp[当前]=0
返回0
#分开
#案例1:如果相同的糖果
如果条[current-1]==条[current]和条[current]==条[current+1]:
如果dp[电流+1]=-1:
dp[current+1]=countContinuitiveSets(current+1)
dp[电流]=dp[电流+1]
返回dp[当前]
#案例2:如果不同的糖果
案例2.1:考虑当前
如果dp[电流+3]=-1:
dp[当前+3]=countcontinuevesets(当前+3)
电流=1+dp[电流+3]
#案例2.2:忽略电流
如果dp[电流+1]=-1:
dp[current+1]=countContinuitiveSets(current+1)
无电流=dp[电流+1]
#结合
dp[电流]=最大值(有电流,无电流)
返回dp[当前]
ConcertiveSetsCount=CountConcertiveSets(1)
返回长度(bar)-3*连续设置


测试用例:

bar=“cccssscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscs 答复:39

但上面的代码给出了6

我的想法有什么问题&如何解决





•㪞דבקן的逻辑:

def CountRemainingCandies(self,bar):
dp=[-1]*长度(巴)
def计数器连续设置(当前):
#解决小的子问题

如果电流<P>,因为序列必须由三的精确块构成,我们可以把每个正方形看作序列中最后一个块中的第三个。请注意,我们还可以通过只更新四个单元格将空间减少到
O(1)

JavaScript代码:

//返回序列长度,
//不是问题答案,哪一个
//巧克力的长度是多少
//删除序列后。
功能f(s){
如果(s.长度<3)
返回0
设dp=新数组(s.length+1)。填充(0)
设best=0

对于(i=2;i),因为序列必须由三的精确块构成,所以我们可以将每个正方形看作序列中最后一个块中的第三个。注意,我们也可以通过更新四个单元来将空间缩小为<代码> O(1)< /代码>。 JavaScript代码:

//返回序列长度,
//不是问题答案,哪一个
//巧克力的长度是多少
//删除序列后。
功能f(s){
如果(s.长度<3)
返回0
设dp=新数组(s.length+1)。填充(0)
设best=0

对于(让i=2;i这是Python中自上而下的工作(
f(str,i)
返回一个元组,
(总体最佳,序列长度向上到i
):

#返回序列长度,
#不是问题答案,哪一个
#巧克力的长度是多少
#删除序列后。
def f(s、i、备忘录):
如果我在备忘录中:
返回备忘录[i]
如果i<2:
返回(0,0)
(最佳)=f(s,i-1,备忘录)
如果s[i]!=s[i-1]或s[i]!=s[i-2]:
序号=3+f(s,i-3,备忘录)[1]
其他:
seq_len=0
备注[i]=(最大值(最佳值,序号),序号)
返回备忘录[i]
s=“cccscssscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscs
印刷品(f(s,len(s)-1,{}[0])#51

这里是Python中自上而下的工作(
f(str,i)
返回一个元组,
(总体最佳,序列长度向上到)
):

#返回序列长度,
#不是问题答案,哪一个
#巧克力的长度是多少
#删除序列后。
def f(s、i、备忘录):
如果我在备忘录中:
返回备忘录[i]
如果i<2:
返回(0,0)
(最佳)=f(s,i-1,备忘录)
如果s[i]!=s[i-1]或s[i]!=s[i-2]:
序号=3+f(s,i-3,备忘录)[1]
其他:
seq_len=0
备注[i]=(最大值(最佳值,序号),序号)
返回备忘录[i]
s=“cccscssscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscscs
印刷品(f(s,len(s)-1,{}[0])#51

为了便于理解,您能将其转换为自顶向下的方法吗?我尝试了自顶向下的方法。它给出了相同的错误答案。请参考问题的底部。@Anil谢谢,自顶向下的代码返回了长字符串的错误答案,但自下而上的方法似乎有效(90-51=39)。我将再次检查自上而下。为便于理解,请将其转换为自上而下的方法。我尝试了自上而下的方法。它给出了相同的错误答案。请参考问题的底部。@Anil谢谢,自上而下的代码返回了长字符串的错误答案,但自下而上的方法似乎有效(90-51)=
# Returns the sequence length,
# not the problem answer, which
# is the length of the chocolate
# after removing the sequence.
def f(s, i, memo):
  if i in memo:
    return memo[i]

  if i < 2:
    return (0, 0)

  (best, _) = f(s, i-1, memo)

  if s[i] != s[i-1] or s[i] != s[i-2]:
    seq_len = 3 + f(s, i - 3, memo)[1]
  else:
    seq_len = 0

  memo[i] = (max(best, seq_len), seq_len)
  return memo[i]

s = "CCCSCCSSSCSCCSCSSCSCCCSSCCSCCCSCCSSSCCSCCCSCSCCCSSSCCSSSSCSCCCSCSSCSSSCSSSCSCCCSCSCSCSSSCS"

print(f(s, len(s) - 1, {})[0]) # 51