Algorithm 带乘法器的动态规划板

Algorithm 带乘法器的动态规划板,algorithm,dynamic-programming,Algorithm,Dynamic Programming,我遇到了相当标准的DP问题-电路板nxn带有整数,都是正数。我想从第一行的某个地方开始,在最后一行的某个地方结束,然后尽可能多地积累。从字段(i,j)我可以转到字段(i+1,j-1),(i+1,j),(i+1,j+1)。 这是相当标准的DP问题。但是我们加了一件事——字段上可以有一个星号,而不是数字。如果我们遇到星号,那么我们从中得到了0点,但我们将乘数增加了1。我们稍后在遍历过程中收集的所有数字都将乘以乘数。 我不知道如何用那个乘法器来解决这个问题。我假设这仍然是一个DP问题,但是如何得到正确

我遇到了相当标准的DP问题-电路板
n
x
n
带有整数,都是正数。我想从第一行的某个地方开始,在最后一行的某个地方结束,然后尽可能多地积累。从字段
(i,j)
我可以转到字段
(i+1,j-1)
(i+1,j)
(i+1,j+1)
。 这是相当标准的DP问题。但是我们加了一件事——字段上可以有一个星号,而不是数字。如果我们遇到星号,那么我们从中得到了
0
点,但我们将乘数增加了
1
。我们稍后在遍历过程中收集的所有数字都将乘以
乘数
。 我不知道如何用那个乘法器来解决这个问题。我假设这仍然是一个DP问题,但是如何得到正确的方程呢


感谢您的帮助。

您仍然可以使用DP,但您必须跟踪两个值:“基本”值,即不使用任何乘数的值,以及“有效”值,即使用乘数的值。从上一行到最后一行开始,在网格中向后移动,然后获取该行中的三个“相邻”单元格(路径上可能的“下一个”单元格),然后只选择值最高的单元格

如果当前单元格是
*
,则得到
base+effective
最大的单元格,否则只得到
effective
得分最高的单元格

下面是Python中的一个示例实现。请注意,我不是使用
*
而是使用
0
作为乘法器,我是按顺序而不是反向循环网格,因为这样更方便

随机导入
尺寸=5
grid=[[random.randint(0,5)表示范围内(大小)]表示范围内(大小)]
打印(*网格,sep=“\n”)
#第一个值是基础分数,第二个值是有效分数(带乘数)
解决方案=[[(x,x)用于行中的x]用于网格中的行]
对于范围内的i(1,尺寸):
对于范围内的k(尺寸):
#前一行中的2或3个值
上一个值=溶液[i-1][max(0,k-1):k+2]
val=网格[i][k]
如果val==0:
#倍增
基数,mult=max(上一个值,key=lambda t:t[0]+t[1])
解决方案[i][k]=(基本、基本+多)
其他:
#加
基数,mult=max(上一个值,key=lambda t:t[1])
解决方案[i][k]=(val+base,val+mult)
打印(*解决方案,sep=“\n”)
打印(最大值(解决方案[-1],密钥=λt:t[1]))
示例:随机5x5网格,其
0
对应于
*

[4, 4, 1, 2, 1]
[2, 0, 3, 2, 0]
[5, 1, 3, 4, 5]
[0, 0, 2, 4, 1]
[1, 0, 5, 2, 0]
最终的
解决方案
网格,包含基本值和有效值:

[( 4,  4), ( 4,  4), ( 1,  1), ( 2,  2), ( 1,  1)]
[( 6,  6), ( 4,  8), ( 7,  7), ( 4,  4), ( 2,  4)]
[( 9, 13), ( 5,  9), ( 7, 11), (11, 11), ( 9,  9)]
[( 9, 22), ( 9, 22), ( 9, 13), (11, 15), (12, 12)]
[(10, 23), ( 9, 31), (14, 27), (13, 17), (11, 26)]

因此,该网格的最佳解决方案是来自
(9,31)
31
。通过网格
解决方案
网格向后工作,这对应于路径
0-0-5-0-4
,即
3*5+4*4=31
,因为
5
之前有2个
*
,而
4
之前有3个
*
,请花一些时间阅读,尤其是命名和。也请和。最后,请学习如何创建一个。因此,乘数只影响后面遇到的数字,这是正确的吗?那么,为什么不从最后一行开始,然后向后走呢?是的,以后再做。你应该发布一个(小)示例网格和该网格的最佳解决方案。我会建议继续遍历
(I,j,mult)
的三维空间,但这显然更好。(虽然我的版本要求不那么聪明。)@b我一点也不确定这在所有情况下都是正确的。如果你自己已经接近一个解决方案,请继续,让我们比较结果。我想有一个建议,乘数应该是乘的,而不是加法。说这个是基于这个问题的。@zenwraight好吧,它是乘以重复加法。请参见答案底部的示例。@tobias_k我还没有写任何代码。:-)但想法很简单。只需将数据保存在一个字典中,该字典的键是元组,其中既包括您所在的位置,也包括状态。那么,这是一个直截了当的前进。