日记★DP★B-01背包问题
来源:互联网 发布:王家卫句式知乎 编辑:程序博客网 时间:2024/06/05 15:03
- B-01背包问题
- 题目
- 题目描述
- 输入
- 输出
- 样例输入
- 样例输出
- 状态定义
- 状态转移
- 边界
- 输出解
- 代码
- 优化-滚动数组
- 题目
B-01背包问题
题目
时间限制: 1 Sec 内存限制: 64 MB
题目描述
有 n 件物品, 每件物品有一个价值和一个重量,分别记为: b1,b2, …bn w1,w2, …wn 其中所有的 重量wi 均为整数。 现有一个背包,其最大载重量为W,要求从这n件物品中任取若干件(这些物品要么被装入要么被留下)。问背包中装入哪些物品可使得所装物品的价值和最大?
输入
第1行:2个整数n(1<=n<=1000)和W(1<=W<=10000),分别表示物品的件数和背包的最大载重量。
第2-n+1行:每行2个用空格分开的整数,第i+1行的整数表示第i件物品的重量wi和价值bi(1<=bi,wi<=10000)。
输出
第1行:1个整数,表示背包所能装下的物品的最大总价值。
第2-?行:每行3个用空格分开的整数,i, wi, bi,分别表示最优解中的物品的编号、重量和价值。
样例输入
4 5
2 3
3 4
4 5
5 6
样例输出
7
1 2 3
2 3 4
状态定义
状态转移
分2种情况,选
- 选
i :f[i][j]=f[i−1][j−w[i]]+b[i] ; - 不选
i :f[i][j]=f[i−1][j] 。
但我们不可能两种情况都要,所以取大的一个:
边界
无。
输出解
用
f[i][j]==f[i−1][j−w[i]]=>Ans[i][j]=1 f[i][j]==f[i−1][j]=>Ans[i][j]=0
然后递归输出即可。
代码
#include<cstdio>#include<algorithm>using namespace std;int read(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f;}#define MAXN 1000#define MAXW 10000int w[MAXN+5],b[MAXN+5];int f[MAXN+5][MAXW+1];bool Ans[MAXN+5][MAXW+5];int N,W;void print(int i,int j){ if(i<1||j<0) return; if(Ans[i][j])//当Ans[i][j]==1时,f[i][j]=f[i-1][j-w[i]]+b[i],表示要选i { print(i-1,j-w[i]); printf("%d %d %d\n",i,w[i],b[i]); } else print(i-1,j);//否则是不选i的,就不用输出}int main(){ N=read(),W=read(); for(int i=1;i<=N;i++) w[i]=read(),b[i]=read(); for(int i=1;i<=N;i++) for(int j=0;j<=W;j++) { if(j>=w[i]&&f[i-1][j]<f[i-1][j-w[i]]+b[i]) { f[i][j]=f[i-1][j-w[i]]+b[i]; Ans[i][j]=1;//其实不用Ans也可以,在递归的时候比较f[i][j]和f[i-1][j-w[i]]+b[i]即可 } else f[i][j]=f[i-1][j]; } printf("%d\n",f[N][W]); print(N,W);}
优化-滚动数组
和A题一样,
但是这样就不能不用
详细内容请看:为什么01背包要逆序循环。
#include<cstdio>#include<algorithm>using namespace std;int read(){ int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();} return x*f;}#define MAXN 1000#define MAXW 10000int w[MAXN+5],b[MAXN+5];int f[MAXW+1];bool Ans[MAXN+5][MAXW+5];int N,W;void print(int i,int j){ if(i<1||j<0) return; if(Ans[i][j]) { print(i-1,j-w[i]); printf("%d %d %d\n",i,w[i],b[i]); } else print(i-1,j);}int main(){ N=read(),W=read(); for(int i=1;i<=N;i++) w[i]=read(),b[i]=read(); for(int i=1;i<=N;i++) for(int j=W;j>=0;j--)//倒着来 if(j>=w[i]&&f[j]<f[j-w[i]]+b[i]) { f[j]=f[j-w[i]]+b[i]; Ans[i][j]=1; } printf("%d\n",f[W]); print(N,W);}
阅读全文
0 0
- 日记★DP★B-01背包问题
- 日记★DP★C-完全背包
- DP 背包问题 01背包
- HDU1203 DP 01背包问题
- 01背包问题 第一次DP
- dp-01背包问题代码
- 01背包问题(动态规划DP)
- POJ 状态DP+ 01 背包问题
- NYOJ - 苹果(dp-01背包问题)
- poj3624 Charm Bracelet DP 01背包问题
- OpenJudge_P8785 装箱问题(DP+01背包)
- 01背包问题--dp动态规划
- 01背包问题(DP解决)
- 解决01背包问题的DP方法
- 采药 水题 dp 01背包问题 luogu1048
- hdu 1574 RP问题 dp 01背包
- dp 背包问题01的优化
- 01背包问题讲解(dp)
- TensorFlow 辨异 —— tf.placeholder 与 tf.Variable
- 第一阶段-入门详细图文讲解tensorflow1.4 -(五)MNIST-CNN
- ros-teleop-indigo_1.0.0.apk 遥控先锋
- Java学习路线
- Pro JavaFX 9, 4th Edition.pdf 2017英文原版 免费下载
- 日记★DP★B-01背包问题
- python简介
- 程序员面试、算法研究、编程艺术、红黑树、机器学习5大系列集锦
- xml学习笔记④PHP DOM--增删改查综合案例演示
- 指针与二维数组 行指针与列指针
- java 权重随机数算法
- TensorFlow 中三种启动图 用法
- 日记★DP★C-完全背包
- MFC的消息映射机制