[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值

[动态规划] (七) 路径问题:LCR 166./剑指offer 47. 珠宝的最高价值

文章目录

      • [动态规划] (七) 路径问题:LCR 166./剑指offer 47. 珠宝的最高价值
        • 题目解析
        • 解题思路
          • 状态表示
          • 状态转移方程
          • 初始化和填表顺序
        • 返回值
        • 代码实现
        • 总结

LCR 166. 珠宝的最高价值

[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值_第1张图片

题目解析

(1) 二维矩阵中存放的是每个珠宝的价值

(2) 从左上角取到右下角

(3) 只能向右或者向下移动

解题思路

[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值_第2张图片

状态表示

按照以往的经验:dp[i] [j] 以(i,j)位置为终点,得到的珠宝总价值。

状态转移方程

以状态表示可以得出:

dp(i,j)取决于两个位置的价值:dp(i-1,j)和dp(i, j-1)。

所以dp(i,j)就等于它们两个的最大值,再加上(i,j)位置对应的价值。

所以

dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + (i,j)位置对应的价值
初始化和填表顺序
  • 初始化

[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值_第3张图片

初始化时,只需要处理一下第一行和第一列的边界情况即可。

所以我们多开辟一列和一行(蓝色格子),又由于 dp(i,j)就等于它们两个的最大值,再加上(i,j)位置对应的价值。所以我们只需要将多开辟的初始化为0即可。我们在创建dp数组时,扩容后正好是0。

  • 填表顺序

一列一列填表即可。

返回值

多开辟一列和一行,返回dp[m] [n]即可。

看到这里,大家可以先尝试实现代码,再接下来看下面的内容。


代码实现
class Solution {
public:
    int jewelleryValue(vector<vector<int>>& frame) {
        //创建dp数组
        int m = frame.size(), n = frame[0].size();
        vector<vector<int>> dp(m+1, vector<int>(n+1));
        //初始化
        // dp[1][1] = frame[0][0];
        //填表
        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];
    }
};

[动态规划] (七) 路径问题:LCR 166.剑指offer 47. 珠宝的最高价值_第4张图片

总结

细节:多开辟一列一行,相当于我们将下标向右下方移动。所以最后在找原数组中对应位置,行和列下标应该都进行减1。如,frame[i-1] [j-1]

你可能感兴趣的:(LEETCODE,动态规划,算法)