读背包九讲之二——完全背包
来源:互联网 发布:淘宝开店怎么上传宝贝图片 编辑:程序博客网 时间:2024/06/01 10:26
没想到完全背包还有如此神奇的写法。学习了。
还了解了和快速求幂类似的二进制思想。
对于为什么完全背包能够这样直接从s[i][1]到v遍历可行并且必须这样,可以从两个层面理解。一是从抽象的概念角度,也就是文章里所说的,对于状态dp[j],由于可能多次取到同一个物品,所以从已经遍历的方向向未遍历的方向遍历是正确的,并且只有以这个方向遍历才是正确的。而是从具体的代码执行流程考虑,假设dp[j]第一次取到了物品i,当j,也就是背包容量增加到j+s[i][1]时,由于可以比较此时的dp[j']与dp[j]+s[i][0],故仍有可能再次取到第i个物品。
实在是妙,太妙了,让我自己是怎么都无法想像还能这样解决完全背包问题,关键是自己习惯并且只会进行形象思维,严密的逻辑思维是在太缺乏了。这种解法所蕴含的思维方式,其实是多么自然多么强大啊。
例题做的poj1384,这里还涉及另一个问题,背包状态的初始化,这里要求背包装满,于是未装满的背包的价值是未定义的,不合理的,于是用-1来标记。具体的处理就是,只有合理的背包才参与选择。
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int MAXN=510,MAXV=10005;int dp[MAXV],s[MAXN][2];int main(){ int T,a,b,n,v; scanf("%d",&T); while(T--){ scanf("%d %d",&a,&b); v=b-a; dp[0]=0; for(int i=1;i<=v;i++) dp[i]=-1; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d %d",&s[i][0],&s[i][1]); for(int i=1;i<=n;i++){ for(int j=s[i][1];j<=v;j++){ if(dp[j-s[i][1]]>=0&&dp[j]>0) dp[j]=min(dp[j],dp[j-s[i][1]]+s[i][0]); else if(dp[j-s[i][1]]>=0) dp[j]=dp[j-s[i][1]]+s[i][0]; } } if(dp[v]>0) printf("The minimum amount of money in the piggy-bank is %d.\n",dp[v]); else printf("This is impossible.\n"); } return 0;}
0 0
- 读背包九讲之二——完全背包
- 背包九讲——完全背包
- 背包九讲——完全背包
- 背包九讲——完全背包
- 背包问题九讲之二 完全背包问题
- 背包九讲之完全背包问题
- 完全背包(背包九讲)
- 背包九讲系列1——01背包、完全背包、多重背包
- 背包九讲之二 P02: 完全背包问题
- 完全背包(背包九讲之2)
- 背包九讲——01背包
- 背包九讲——多重背包
- 背包九讲——多重背包
- 背包九讲 P02: 完全背包问题
- 【背包九讲】P02: 完全背包问题
- 背包九讲笔记-完全背包问题
- 背包九讲-完全背包-HDU1114
- 动态规划&背包九讲&完全背包
- CocoaPods详解之----制作篇
- unity之数组
- Android 4.0的图形硬件加速及绘制技巧
- Oracle-SQL_TRACE使用
- 消息栏的应用
- 读背包九讲之二——完全背包
- void及void指针含义的深刻解析(好文章)
- 一道mysql面试题,觉得有些伤脑经,记录下来
- 黑马程序员-开篇日记
- 面试
- VC中HDC与CDC的区别
- Digital Roots(杭电1013)(字符串处理)(大数)
- C++primer(第五版)第五章总结(含部分习题源代码及解析)语句
- 基于HT for Web 3D呈现Box2DJS物理引擎