【剑指offer】46.礼物的最大价值
总目录:
1.问题描述
在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于 0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向右或者向下移动一格、直到到达棋盘的右下角。给定一个棋盘及其上面的礼物的价值,请计算你最多能拿到多少价值的礼物?
如输入这样的一个二维数组,
[
[1,3,1],
[1,5,1],
[4,2,1]
]
[
[1,3,1],
[1,5,1],
[4,2,1]
]
那么路径 1→3→5→2→1 可以拿到最多价值的礼物,价值为12
2.问题分析
注意这并不是贪心算法,都需要建立状态转移方程
dp[rowId][colId] = max(dp[rowId][colId-1], dp[rowId-1][colId]) + grid[rowId][colId];
1记忆化搜索
建立dp表,建完表之后即可直接返回指定坐标的dp值,也需要状态转移方程
2动态规划
不需要建立dp表,直接把dp值放在原表中
3.代码实例
记忆化搜索

1 #include <algorithm> 2 class Solution { 3 public: 4 /** 5 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 6 * 7 * 8 * @param grid int整型vector<vector<>> 9 * @return int整型 10 */ 11 //返回值:-1:没有前一个dp,0:左侧dp较大,1:上侧dp较大 12 vector<vector<int>> dpMap; 13 int getMaxDp(vector<vector<int> >& grid, 14 int rowId, int colId) { 15 //超限 16 if (rowId < 0 || colId < 0) {//不能再移动 17 return 0; 18 } 19 20 //该单元格的计算尚需计算 21 if (dpMap[rowId][colId] <= 0) { 22 int leftDp = colId <= 0 ? 0 : getMaxDp(grid, rowId, colId - 1); 23 int upDp = rowId <= 0 ? 0 : getMaxDp(grid, rowId - 1, colId); 24 dpMap[rowId][colId] = max(leftDp, upDp) + grid[rowId][colId]; 25 } 26 27 return dpMap[rowId][colId]; 28 } 29 30 int maxValue(vector<vector<int> >& grid) { 31 if (grid.size() <= 0 || grid[0].size() <= 0) { 32 return 0; 33 } 34 35 int rowCnt = grid.size(); 36 int colCnt = grid[0].size(); 37 38 //计算dpMap 39 for (int i = 0; i < rowCnt; i++) {//行遍历 40 dpMap.push_back(vector<int> {}); 41 for (int j = 0; j < colCnt; j++) {//列遍历 42 dpMap[i].push_back(0); 43 dpMap[i][j] = getMaxDp(grid, i, j); 44 } 45 } 46 47 return dpMap[rowCnt - 1][colCnt - 1]; 48 } 49 };
动态规划
1 class Solution { 2 public: 3 int maxValue(vector<vector<int> >& grid) { 4 int m = grid.size(); 5 int n = grid[0].size(); 6 //第一列只能来自上方 7 for(int i = 1; i < m; i++) 8 grid[i][0] += grid[i - 1][0]; 9 //第一行只能来自左边 10 for(int i = 1; i < n; i++) 11 grid[0][i] += grid[0][i - 1]; 12 //遍历后续每一个位置 13 for(int i = 1; i < m; i++) 14 for(int j = 1; j < n; j++) 15 //增加来自左边的与上边的之间的较大值 16 grid[i][j] += max(grid[i - 1][j], grid[i][j - 1]); 17 return grid[m - 1][n - 1]; 18 } 19 };