You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态规划进阶问题:二维矩阵最大幸福值路径求解

嘿,这个动态规划的问题卡在这里很正常,核心难点就是连续左移的扣减计数会影响后续的幸福值计算,原来只记录(i,j)位置的最大幸福值肯定不够,得把连续左移的状态也加进DP里才行!我给你一步步拆解:

1. 重新设计DP状态

我们需要把「连续左移的次数」作为状态的一部分,这样才能准确计算扣减:
定义 dp[i][j][k] 表示:

  • 到达单元格 (i,j) 时,最后一步是连续第 k 次左移(k=0 表示最后一步是向下移动,或者刚跳到这一行还没左移)
  • 存储的值是该状态下能获得的最大幸福值

2. 基础情况初始化

  • 起点是右上角 (0, m-1),此时没有任何移动,连续左移次数为0,所以 dp[0][m-1][0] = Happiness[0][m-1]
  • 根据规则1,我们可以直接跳过任意行到某一行的最右列(j=m-1),所以所有 dp[i][m-1][0] 都可以初始化为 Happiness[i][m-1](相当于直接从起点跳过来)
  • 其他所有状态先初始化为负无穷,表示暂时不可达

3. 状态转移逻辑

我们按列从右到左遍历(因为向左移动依赖右侧列的状态),行可以从上到下遍历,分两种转移情况:

情况1:从上方(或任意上一行)向下移动到 (i,j)

此时到达 (i,j) 后,连续左移次数重置为0,我们需要取所有上一行(包括跳过多行的情况)的最大幸福值加上当前单元格的幸福值:

# 可以维护一个row_max数组,记录每列j目前为止的最大幸福值,优化跳过任意行的计算
row_max[j] = max(row_max[j], max(dp[i-1][j][k] for k in range(max_possible_k)))
dp[i][j][0] = row_max[j] + Happiness[i][j]

如果不想维护row_max,也可以直接遍历所有 x < i 的行,取 dp[x][j][*] 的最大值,只是效率稍低。

情况2:从右侧 (i,j+1) 向左移动到 (i,j)

这里要根据右侧状态的连续左移次数计算扣减:

  • 如果右侧状态是 k_prev=0(最后一步是向下):这次是首次左移,扣减1,当前连续左移次数变为1
    dp[i][j][1] = max(dp[i][j][1], dp[i][j+1][0] + Happiness[i][j] - 1)
    
  • 如果右侧状态是 k_prev>=1(已经连续左移了k_prev次):这次是第 k_prev+1 次左移,扣减 k_prev+1,当前连续左移次数变为 k_prev+1
    dp[i][j][k_prev+1] = max(dp[i][j][k_prev+1], dp[i][j+1][k_prev] + Happiness[i][j] - (k_prev+1))
    

4. 最终结果

终点是左下角 (n-1, 0),我们只需要取这个位置所有可能的连续左移次数对应的最大幸福值:

max_happiness = max(dp[n-1][0][k] for k in range(max_possible_k))

举个小例子验证

比如一个3x3的幸福矩阵:

Happiness = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
  • 初始化所有 dp[i][2][0] 为对应值:dp[0][2][0]=3,dp[1][2][0]=6,dp[2][2][0]=9
  • 向下转移到 (1,2):dp[1][2][0] = max(3+6,6)=9;向下到 (2,2):dp[2][2][0] = max(9+9,9)=18
  • 向左到 (2,1):dp[2][1][1] = 18 +8 -1=25
  • 向左到 (2,0):dp[2][0][2] =25 +7 -2=30
  • 最终最大值就是30,符合预期

这样设计状态后,就能完美跟踪连续左移的扣减次数,找到最优路径啦!

内容的提问来源于stack exchange,提问作者forfun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 06:51:04