文章目录


剑指 Offer 47. 礼物的最大价值(DP)_贪心算法

​剑指 Offer 47. 礼物的最大价值​

二维dp

剑指 Offer 47. 礼物的最大价值(DP)_算法_02


当前格的最大价值(dp[i][j])等于当前格子价值(grid[i][j])加上左边格子最大价值(dp[i][j-1])和上边格子最大价值(dp[i-1][j])较大者

class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
// 开辟和grid一样大的dp数组
vector<vector<int>> dp(m, vector<int>(n, 0));
// 初始化第0行和第0列的礼物最大值
dp[0][0] = grid[0][0];
for(int j = 1; j < n; j++){
dp[0][j] += dp[0][j-1] + grid[0][j];
}
for(int i = 1; i < m; i++){
dp[i][0] += dp[i-1][0] + grid[i][0];
}
// 从[1][1]开始逐行求出礼物最大值
for(int i = 1; i < m; i++){
for(int j = 1; j < n; j++){
dp[i][j] = grid[i][j] + max(dp[i-1][j], dp[i][j-1]);
}
}
return dp[m-1][n-1];
}
};

简化边界处理:我们多开辟一行一列,并将第0行和第0列的值初始化为0,这样就能统一成grid当前值+max(上方最大价值,左侧最大价值)

剑指 Offer 47. 礼物的最大价值(DP)_算法_03

class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();

vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));

// i与一维dp数组无关
for(int i = 1; i <= m; i++){
for(int j = 1; j <= n; j++){
dp[i][j] = grid[i-1][j-1] + max(dp[i][j-1], dp[i-1][j]);
}
}
return dp[m][n];
}
};

滚动数组降维

​初学者学习,礼物的最大价值​

把紫色部分当成一维dp数组

剑指 Offer 47. 礼物的最大价值(DP)_i++_04


剑指 Offer 47. 礼物的最大价值(DP)_数组_05

class Solution {
public:
int maxValue(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();

vector<int> dp(n + 1, 0);

for(int i = 0; i < m; i++){
for(int j = 1; j <= n; j++){
dp[j] = max(dp[j-1], dp[j]) + grid[i][j-1];
}
}
return dp[n];
}
};