JZ47 礼物的最大价值
JZ47 礼物的最大价值
描述
在一个$m×n$的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
如输入这样的一个二维数组,
1 | [ |
那么路径 $1\to3\to5\to2\to1$ 可以拿到最多价值的礼物,价值为12
示例1
1 | 输入:[[1,3,1],[1,5,1],[4,2,1]] |
备注
$0<grid.length≤200 $
$0<grid[0].length≤200$
题解
同样的,拆解问题,我们只能考虑从左上角向右还是向下移动,直到到达右下角,所以每一次的操作只能考虑向右还是下移动。反过来也可以考虑从右下角往左上移动,二者是相似的,重点在于如何找到那条值的和最大的路径。
到达某个位置的礼物价值最大和是一定的,设为$dp[i][j]$,那么$dp[i][j]=max(dp[i-1][j],dp[i][j-1])+grid[i][j]$
由于到达最上方一列和最左侧一列都只有一条路径,那么可以获得初始条件:
$$
dp[i][0]=\sum_{k=0}^{i}grid[k][0]\
dp[0][j]=\sum_{k=0}^{j}grid[0][k]
$$
最后可以由递归直接获得$dp[m][n]$返回即可。
代码
1 |
|
没想出来怎么优化,问了大G老师,大G老师说把二维数组$dp$压成一维数组,看完了懂了,在遍历过程中,实际上只需要上一行的信息以及左侧一个的信息即可,上一行的信息用$dp_pre$存储,左侧一个的用$left$存储即可。