剑指 Offer 47. 礼物的最大价值
在一个 m*n 的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
示例 1:
输入:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
输出: 12
解释: 路径 1→3→5→2→1 可以拿到最多价值的礼物
提示:
0 < grid.length <= 200
0 < grid[0].length <= 200
思路;
根据题目说明,易得某单元格只可能从上边单元格或左边单元格到达。
- 对于第一行的单元格,肯定只能从左边过来
- 对于第一列的单元格,肯定只能从上边过来
- 对于不是第一行或第一列的单元格,是从上边或左边大的那个单元格过来
设 f(i, j) 为从棋盘左上角走至单元格 (i ,j) 的礼物最大累计价值易得到以下递推关系:
f(i,j) 等于 f(i,j-1) 和 f(i-1,j) 中的较大值加上当前单元格礼物价值 grid(i,j)。
即
f(i,j) = grid(i,j) + Math.max(f(i, j − 1), f(i − 1, j))。
f(i,j)就是最大的价值;就是每次和当前位置的上和左中选出一个最大值和当前位置相加,就是最大的值;第一行由于没有上所以只和左面相加,第一列由于没有左所以只和上相加。
class Solution {
public int maxValue(int[][] grid) {
int x=grid.length,y=grid[0].length;//行x列y遍历二维数组
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
if(i==0&&j==0) continue;//开始直接跳过
if(i==0) grid[i][j]+=grid[i][j-1];//第一行没有上,直接和左相加因为只能从左进
else if(j==0) grid[i][j]+=grid[i-1][j];//第一列没有左,直接和上相加因为只能从上进
else grid[i][j]+=Math.max(grid[i-1][j],grid[i][j-1]);//其余位置和两个进入的可能上和左选一个最大的进入和当前位置相加
}
}
return grid[x-1][y-1];//右下角就是最后一个上左进入之后的位置和当前位置相加的,所以是最大的
}
}