题目描述:
输入示例:
解题思路:
本题是典型的动态规划题,求m行n列的最大价值可以从grid[m - 1][n - 1]的左边或者上面的状态中选取较大的价值,再加上本身的价值。
即dp(i,j) 等于 dp(i,j-1)和 dp(i-1,j)中的较大值加上当前单元格礼物价值 grid(i,j)。
动态转移方程为:dp[j] = Math.max(dp[j],dp[j - 1]) + grid[i - 1][j - 1];
代码实现如下:
class Solution {
public int maxValue(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[][] dp = new int[m][n];
dp[0][0] = grid[0][0];
for (int i = 1;i < m;i++) {
dp[i][0] = dp[i - 1][0] + grid[i][0];
}
for (int i = 1;i < n;i++) {
dp[0][i] = dp[0][i - 1] + grid[0][i];
}
for (int i = 1;i < m;i++) {
for (int j = 1;j < n;j++) {
dp[i][j] = Math.max(dp[i - 1][j],dp[i][j - 1]) + grid[i][j];
}
}
return dp[m - 1][n - 1];
}
}
动态规划是一种以空间换时间的算法,我们是重新定义了一个二维数组,二维数组的每个值都对应了相应位置计算过后的礼物最大价值,但是我们最后实际要用到的只有最后一行(列)和最后一行(列)的前一行(列),所以这里可以换成一位数组来做。也就是滚动数组,数组一直在变化。
代码实现如下:
class Solution {
public int maxValue(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int[] dp = new int[n + 1];
for (int i = 1;i < m + 1;i++) {
for (int j = 1;j < n + 1;j++) {
dp[j] = Math.max(dp[j],dp[j - 1]) + grid[i - 1][j - 1];
}
}
return dp[n];
}
}