1. 题目链接:LCR 166. 珠宝的最高价值
2. 题目描述:
现有一个记作二维矩阵
frame
的珠宝架,其中frame[i][j]
为该位置珠宝的价值。拿取珠宝的规则为:
- 只能从架子的左上角开始拿珠宝
- 每次可以移动到右侧或下侧的相邻位置
- 到达珠宝架子的右下角时,停止拿取
注意:珠宝的价值都是大于 0 的。除非这个架子上没有任何珠宝,比如
frame = [[0]]
。示例 1:
输入: frame = [[1,3,1],[1,5,1],[4,2,1]] 输出: 12 解释: 路径 1→3→5→2→1 可以拿到最高价值的珠宝
提示:
0 < frame.length <= 200
0 < frame[0].length <= 200
3. 解法(动态规划)
3.1 算法思路:
3.1.1 状态表示:
dp[i][j]
表示:走到[i,j]
位置处,此时的最大价值
3.1.2 状态转移方程:
对于dp[i][j]
,我们发现需要到达[i,j]
位置,有两种方式:
-
从
[i,j]
位置的上方[i-1,j]
位置,向下走一步,此时到达[i,j]
位置能拿到的珠宝价值为dp[i-1][j]+ frame[i][j]
; -
从
[i][j]
位置的左边[i,j-1]
位置,向右走一步,此时到达[i,j]
位置能拿到的礼物价值为dp[i][j-1]+ frame[i][j]
;
我们要拿的是最大值,因此状态转移方程为:dp[i][j]=max(dp[i-1][j],dp[i][j-1])+ frame[i][j]
3.1.3 初始化:
可以在最前面加上一个辅助结点,帮助我们初始化,使用这种技巧要注意两个点:
-
辅助结点里面的值要保证后续填表是正确的
-
下标的映射关系
在本题中,添加一行并且添加一列后,所有的值都为0
即可
3.1.4 填表顺序:
根据状态转移方程,填表的顺序是从上往下
填写每一行,每一行都从左往右
3.1.5 返回值:
根据状态表示,我们应该返回dp[m][n]
的值
3.2 C++算法代码
class Solution {
public:
int jewelleryValue(vector<vector<int>>& frame) {
int m=frame.size(),n=frame[0].size();
//创建dp表
vector<vector<int>> dp(m+1,vector<int>(n+1));
//初始化
//填表
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=max(dp[i-1][j],dp[i][j-1])+frame[i-1][j-1];
}
}
//返回
return dp[m][n];
}
};