剑指Offer(第二版)面试题47:礼物的最大价值
题目要求:
在一个m * n的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘
1 10 3 8
12 2 9 6
5 7 4 11
3 7 16 5
礼物的最大价值为1+12+5+7+7+16+5=53。
解题思路:
- 思路1:动态规划
申请一个与原矩阵行列数一样的二维数组dp[][],初始化dp[0][i] = data[0][i];然后依次更新dp的每一行即可。由于第m行的值与第m-1行和第m行有关,因此可以对dp进行简化,仅用两行的dp,即dp[2][]即可完成状态的记录与更新。
思路2:广度优先遍历
- 这个棋盘其实可以看成一个有向图,起点为左上角,终点为右下角,每一点仅仅指向右侧和下侧。因此我们可以从左上角开始进行广度优先遍历。此外,遍历过程中可以进行剪枝,最终移动到右下角时会仅剩下一个枝,该路径所经的点的数值之和即为所求。
作者:ryderchan
链接:https://www.jianshu.com/p/489098b6c5c3
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
C++代码
#include <iostream>
#include <vector>
using namespace std;
int getMaxValue_solution2(vector<int> mat, int row, int col);
int main()
{
vector<int> mat = {1,10,3,8,12,2,9,6,5,7,4,11,3,7,16,5};
int result = getMaxValue_solution2(mat,4,4);
cout << result <<endl;
return 0;
}
int getMaxValue_solution2(vector<int> mat, int row, int col)
{
int result = -1;
if(mat.empty() || row < 1 || col < 1)
{
return result;
}
int* temp = new int[col];
for(int i = 0; i < row; ++i)
{
for(int j = 0; j < col; ++j)
{
int up = 0;
int left = 0;
if(i > 0)
up = temp[j];
if(j > 0)
left = temp[j-1];
temp[j] = max(left , up) + mat[i * col + j];
}
}
result = temp[col - 1];
delete[] temp;
return result;
}