算法萌新如何学好动态规划(3)( 二 )
确定「DP 状态」后 , 我们来考虑「DP 转移方程」是什么 。
对于第 i 个物品来说 , 它只有两种状态 , 即要么取 , 要么不取 。 如果不取第 i 个物品 , 则
文章插图
;如果取第 i 个物品 , 则
文章插图
, 因此我们得到如下「DP 转移方程」:
文章插图
其中初值
文章插图
为负无穷 , 其中
文章插图
, 最终答案为
文章插图
, 代码如下所示 。
int DP() {for(int i = 1; i <= M; i++)f[0][j] = -inf; // 负无穷 , inf 可以为 1e8f[0][0] = 0;for(int i = 1; i <= N; i++)for(int j = 0; j <= M; j++)if(j >= v[i])f[i][j] = max(f[i-1][j], f[i-1][j-v[i]] + w[i]);elsef[i][j] = f[i-1][j];int ans = 0;for(int i = 0; i <= M; i++)ans = max(ans, f[N][i]);return ans;}
观察上述代码 , 不难发现 ,
文章插图
仅由
文章插图
和
文章插图
决定 。 这就给了我们一个思考角度 , 即能否将二维数组 f 的第一维去掉?
答案显然是可以的 , 我们可以倒序枚举 j , 使得更新
文章插图
时
文章插图
还未被更新 , 即
文章插图
代表的实际是
文章插图
的值 。 这样说可能不好理解 , 我们先看一下优化后的代码:
int DP() {for(int i = 1; i <= M; i++)f[j] = -inf; // 负无穷 , inf 可以为 1e8f[0] = 0;for(int i = 1; i <= N; i++)for(int j = M; j >= v[i]; j++)f[j] = max(f[j], f[j-v[i]] + w[i]);int ans = 0;for(int i = 0; i <= M; i++)ans = max(ans, f[i]);return ans;}
根据上述代码 , 我们不难发现在第 i 轮 , 更新到
文章插图
时 ,
文章插图
与
文章插图
代表的都是第 i - 1 轮的值 , 即
文章插图
与
文章插图
推荐阅读
- 大一非计算机专业的学生,如何利用寒假自学C语言
- 向日葵远程控制企业版客户端更新升级,优化远控UI适配SADDC内核算法
- 红米K40渲染图曝光:居中挖孔+后置四摄,这外观你觉得如何?
- 奋斗|该如何看待拼多多员工猝死:鼓励奋斗,也要保护好奋斗者
- 装机点不亮 如何简易排查硬件问题?
- 虾米音乐宣布关停!我的歌单如何导入QQ音乐、网易云音乐?
- 人脸识别设备主板如何选型 软硬整合大幅缩短开发时间
- Mini-LED产品效果究竟如何?
- 专家介绍如何判断智能手机被入侵:运行速度变慢、电池消耗过快以及卡顿
- 在谷歌算法更新之后2020年盗版网站流量锐减三分之一