您的位置:首页 > 科技 > 能源 > 深圳网站建设服务代码_网站服务是指_网站宣传方式有哪些_网址搜索引擎入口

深圳网站建设服务代码_网站服务是指_网站宣传方式有哪些_网址搜索引擎入口

2024/11/15 16:06:53 来源:https://blog.csdn.net/2301_77329667/article/details/143312258  浏览:    关键词:深圳网站建设服务代码_网站服务是指_网站宣传方式有哪些_网址搜索引擎入口
深圳网站建设服务代码_网站服务是指_网站宣传方式有哪些_网址搜索引擎入口

问题:Leetcode 166.珠宝的最高价值

现有一个记作二维矩阵 frame 的珠宝架,其中 frame[i][j] 为该位置珠宝的价值。拿取珠宝的规则为:

  • 只能从架子的左上角开始拿珠宝
  • 每次可以移动到右侧或下侧的相邻位置
  • 到达珠宝架子的右下角时,停止拿取

注意:珠宝的价值都是大于 0 的。除非这个架子上没有任何珠宝,比如 frame = [[0]]

a7d8bff1eb824f2280b172582fc9c154.png


算法1:递归 寻找子问题(超时)

ce9a52370d124b79b4fc0c84d91d8461.png

受上图启发,定义 dfs ( i , j ) 表示从左上角到第 i 行第 j 列这个格子(记作  ( i , j ) )的最大价值和。

分类讨论怎么到达 ( i , j )

如果是从左边过来,则 dfs ( i , j ) = dfs ( i , j − 1 ) + frame [ i ] [ j ] 
如果是从上边过来,则 dfs ( i , j ) = dfs ( i − 1 , j ) + frame [ i ] [ j ] 

这两取最大值,得 dfs ( i , j ) = max ( dfs ( i , j − 1 ) , dfs ( i − 1 , j ) ) + frame [ i ] [ j ]
递归边界:当 i < 0 j < 0 时,返回 0,因为出界是没有价值的。也就是 dfs ( −1 , j ) = 0 , dfs ( i , − 1 ) = 0 

递归入口:dfs(m−1,n−1)

代码:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {function<int(int,int)>dfs = [&](int i,int j)->int{if(i < 0 || j < 0)  return 0;return max(dfs(i,j-1),dfs(i-1,j)) + frame[i][j];};return dfs(frame.size() - 1,frame[0].size() - 1);}
};

算法2:记忆化搜索

如果一个状态(递归入参)是第一次遇到,那么可以在返回前,把状态及其结果记到一个 memo 数组(或哈希表)中;
如果一个状态不是第一次遇到,那么直接返回 memo 中保存的结果

代码:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m = frame.size(),n = frame[0].size();int memo[m][n]; // memo数组 存放记录memset(memo, 0, sizeof(memo)); // 初始化function<int(int,int)>dfs = [&](int i,int j)->int{if(i < 0 || j < 0)  return 0;int &res = memo[i][j];if(res) return res;return res = max(dfs(i,j-1),dfs(i-1,j)) + frame[i][j];};return dfs(m - 1,n - 1);}
};

 


算法31:1 翻译成递推

代码:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m = frame.size(),n = frame[0].size();int dp[m + 1][n + 1];memset(dp, 0, sizeof(dp));for(int i = 0;i < m;i++)for(int j = 0;j < n;j++)dp[i + 1][j + 1] = max(dp[i + 1][j],dp[i][j + 1]) + frame[i][j];return dp[m][n];}
};

 


算法4:空间优化·方法一(两个数组,滚动数组)

由于 dp [ i + 1 ] 只依赖 dp [ i ] ,那么 dp [ i − 1 ] 及其之前的数据就没用了。

例如计算 dp [ 2 ] 的时候,数组 dp [ 0 ] 不再使用了。

那么干脆把 dp [ 2 ] 填到 dp [ 0 ] 中。同理,把 dp [ 3 ] 填到 dp [ 1 ] 中,dp [ 4 ] 填到 dp [ 0 ] 中,……

因此可以只用两个长为 n+1 的数组滚动计算。

代码:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m = frame.size(),n = frame[0].size();int dp[2][n + 1];memset(dp, 0, sizeof(dp));for(int i = 0;i < m;i++)for(int j = 0;j < n;j++)dp[(i + 1) % 2][j + 1] = max(dp[(i + 1) % 2][j],dp[i % 2][j + 1]) + frame[i][j];return dp[m % 2][n];}
};

算法5:空间优化·方法二(一个数组)

举个例子,在计算 dp [ 1 ] [ 1 ] 时,会用到 dp [ 0 ] [ 1 ] ,但是之后就不再用到了。那么干脆把 dp [ 1 ] [ 1 ] 记到 dp [ 0 ] [ 1 ] 中,这样对于 dp [ 1 ] [ 2 ] 来说,它需要的数据就在 dp [ 0 ] [ 1 ]dp [ 0 ] [ 2 ] 中。dp [ 1 ] [ 2 ] 算完后也可以同样记到 dp [ 0 ] [ 2 ] 中。

所以只需要一个长为 n+1 的一维数组就够了。

代码1:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int m = frame.size(),n = frame[0].size();int dp[n + 1];memset(dp, 0, sizeof(dp));for(int i = 0;i < m;i++)for(int j = 0;j < n;j++)dp[j + 1] = max(dp[j],dp[j + 1]) + frame[i][j];return dp[n];}
};

代码2:

class Solution {
public:int jewelleryValue(vector<vector<int>>& frame) {int n = frame[0].size();int dp[n + 1];memset(dp, 0, sizeof(dp));for(auto &row : frame)for(int j = 0;j < n;j++)dp[j + 1] = max(dp[j],dp[j + 1]) + row[j];return dp[n];}
};

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com