noip2005 一维采药---非恰 (01背包)
来源:互联网 发布:苏联打阿富汗知乎 编辑:程序博客网 时间:2024/05/21 22:39
采药
如果你是辰辰,你能完成这个任务吗?
70 371 10069 11 2
3
讲解:通过前面两篇文章的讲解,相信对采药的基本思路应当有一定头绪,我在这里要讲的是另一种更简洁的思路。
我们在前两篇文章中,对于状态的定义都是恰用体积j,最后输出答案是还要枚举一遍,确实显得有点麻烦。为了偷懒,此时自然会想到在输出答案时,能否直接输出一个值,而不用枚举呢?如果要做到这个的话,显然 “恰” 的状态定义就不合适了。
我们重新定义f[j],表示时间为 j 时 所能获得最大价值,时间 j 不一定全部用完,那么最后的答案就是 f[t] ,而不用再枚举了。
请仔细感受一下“恰”与“非恰”定义的不同。
程序演示:
#include<cstdio>#include<algorithm>#define maxn (1000+10)using namespace std;int t,m,f[maxn];void work(){ int i,j,v,w; for(scanf("%d%d",&t,&m),i=1;i<=m;i++) for(scanf("%d%d",&v,&w),j=t;j>=v;j--) f[j]=max(f[j],f[j-v]+w); printf("%d\n",f[t]);}int main(){ work(); return 0;}
代码解析:枚举到第i个物品,如果不把第i个物品放入背包,则f[j]的最优值为max(f[j],f[j-1]);如果要把第i个物品放入背包,则f[j]的最优值为f[j-v]+w。但为何上面的状态转移方程中并没有f[j-1]呢?这要谈到最优性问题了。
我们对于f[j]的定义是时间为j 时的最优值,则有:(为了方便展示,这里以二维非恰的f[i][j]表示枚举到第i个物品,时间为j时的最优值)
f[i-1][j]>=f[i-1][j-1]
f[i-1][j-v]>=(f[i-1][(j-1)-v])
f[i][j]=max(f[i-1][j],f[i-1][j-v]+w);
f[i][j-1]=max(f[i-1][j-1],f[i-1][(j-1)-v]+w);
===>f[i][j]>=f[i][j-1]
===>f[j]>=f[j-1]
所以状态转移方程中没有f[j-1]。
由上可知,只要我们保证i-1层的最优值,那么第i层必然也是最优的。初始状态,第0层的最优值全为0,由第0层的最优值可以得到第1层的最优值。。。。。以此类推,最终得到第m层的最优值。
到此为止,对于01背包二维转一维的讲解也结束了。如果你还是存在疑惑,请对比三篇文章中的四份代码好好体会一下,如果代码有问题的话,个人建议最最好是自己出一个小数据,t<=10,m<=5比较合适,然后自己按照我的代码,模拟一遍电脑运行的过程,代码理解也就不是大问题了。
有疑问的话,欢迎大家留言,这也有助于我继续完善背包dp这个专题。
0 0
- noip2005 一维采药---非恰 (01背包)
- noip2005 一维采药---恰 (背包dp)
- noip2005 二维采药---恰 (01背包)
- 01背包一维优化(来源:NOIP2005普及组采药)
- NOIP2005-采药问题(0-1背包问题)
- 采药(01背包)
- 采药(01背包)
- 【noip2005】采药
- 采药(NOIP2005)
- 采药(01背包改编)
- 采药问题(01背包)
- (NOIP2005第三题)采药(medic)
- [NOIP2005]采药 T3
- [NOIP2005] 采药-解题报告
- tyvj 1005采药(01背包)
- 采药 01背包
- 01背包????采药
- 【01背包】采药
- Filter--责任链
- Linking Containers Together
- Vakuum开发笔记02 核心与安全问题
- 淘宝IP库应用
- tomcat启动一闪而过
- noip2005 一维采药---非恰 (01背包)
- Leetcode【16】:3Sum Closest
- Android Fragments 详细使用
- vc环境下libssh编译
- 约瑟环问题的数组实现
- 微信订餐系统怎么建设?
- input与select在不同浏览器上的宽度显示不同
- 018
- OS X Mountain Lion 系统配置 Apache+Mysql+PHP 详细教程