剑指 Offer 47. 礼物的最大价值
难度中等250 收藏 分享 切换为英文 接收动态 反馈
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例 1:
<pre style="box-sizing: border-box; font-size: 13px; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; margin-top: 0px; margin-bottom: 1em; overflow: auto; background: rgba(var(--dsw-fill-tertiary-rgb),1); padding: 10px 15px; color: rgba(var(--grey-9-rgb),1); line-height: 1.6; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; white-space: pre-wrap;">输入:
[ [1,3,1], [1,5,1], [4,2,1] ]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物</pre>
提示:
0 < grid.length <= 200
0 < grid[0].length <= 200
思路:
动态规划
需要求的右下角的最大值
先计算第一排和第一列的每个格子的最大值,
a[row][0]=a[row-1][0]+nums[row][0];
然后剩下的格子a[row][column]的最大值是max(a[row-1][column],a[row][column])+nums[row][column]
最后返回右下角的最大值就ok了
class Solution {
public int maxValue(int[][] grid) {
int rows=grid.length;
int columns=grid[0].length;
int[][] dp= new int[rows][columns];
dp[0][0]=grid[0][0];
for(int column=1;column<columns;column++){
dp[0][column]=dp[0][column-1]+grid[0][column];
}
for(int row=1;row<rows;row++){
dp[row][0]=dp[row-1][0]+grid[row][0];
}
for(int column=1;column<columns;column++){
for(int row=1;row<rows;row++){
dp[row][column]=Math.max(dp[row-1][column]+grid[row][column],dp[row][column-1]+grid[row][column]);
}
}
return dp[rows-1][columns-1];
}
}