题目描述
在一个m × n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格,直到到达棋盘的右下角。给定一个棋盘及其上面的礼物价值,请计算你最多能拿到多少价值的礼物?
输入: [ [1,3,1], [1,5,1], [4,2,1] ] 输出: 12 解释:路径 1→3→5→2→1 可以拿到最多价值的礼物解题思路
这是典型二维动态规划,和「不同路径」是同一种网格 DP 模型。
- 状态定义
dp[i][j]:走到原网格frame[i-1][j-1]这个位置时,能拿到礼物的最大价值。
这里 dp 数组下标从 1 开始,目的是省去单独处理第一行、第一列边界的代码,
dp[0][...]和dp[...][0]初始化为 0。
- 状态转移方程机器人只能从上方或者左方走到当前格子,我们选择价值更大的那条路径,再加上当前格子礼物价值:
\(dp[i][j]=\max(dp[i-1][j],dp[i][j-1])+frame[i-1][j-1]\)
- 初始化
dp数组全部初始化为 0,天然满足边界条件。 - 结果最终答案:
dp[m][n],对应网格右下角位置。
class Solution { public: int jewelleryValue(vector<vector<int>>& frame) { int m=frame.size(); int n=frame[0].size(); vector<vector<int>>dp(m+2,vector<int>(n+2,0)); for(int i=1;i<m+1;i++) { for(int j=1;j<n+1;j++) { dp[i][j]=max(dp[i-1][j],dp[i][j-1])+frame[i-1][j-1]; } } return dp[m][n]; } };