背包问题总结(模板)
来源:互联网 发布:网络中的信息交流 编辑:程序博客网 时间:2024/06/05 06:24
01背包:
有n个物品,每个物品对应的价值和体积,且每个物品只能选一次,背包体积为V求背包所能装物品的最大价值
#include<iostream>#include<cstdio>const int maxn=10002;//n表示物品个数 int f[maxn],v[maxn],val[maxn],V,n;//V表示背包体积 using namespace std;//v[]表示物品的体积, int main()//val[]表示物品的价值 {scanf("%d%d",&n,&V);for(int i=1;i<=n;i++){scanf("%d%d",&v[i],&val[i]);}for(int i=1;i<=n;i++) for(int j=V;j>=v[i];j--) f[j]=max(f[j],f[j-v[i]]+val[i]);printf("%d",f[V]); return 0;}完全背包:
和01背包基本类似,不同的只是每种物品可以取无数次;
对于完全背包的一维递推方程,我们只需要更改一下循环方向即可
for(int i=1;i<=n;i++) for(int j=v[i];j<=V;j++) f[j]=max(f[j],f[j-v[i]]+val[i]);//完全背包代码核心;多重背包:
对于每一件物品我们对其规定件数(最多能使用多少件),我们可以对于每一种物品,枚举其件数,对于每一件物品,我们对其的状态只有两种:拿,不拿;所以我们可以转化成为01背包来求解
//第一层我们枚举物品种类//第二层我们枚举背包体积;//第三层我们枚举每种物品的个数 for(int i=1;i<=n;i++)for(int j=V;j>=0;j--) for(int k=0;k<=c[i];k++) if(k*v[i]>j) break;//注意特判 else f[j]=max(f[j],f[j-k*v[i]]+k*val[i]);printf("%d",f[V]);分组背包:
我们来看一下什么是分组背包?
有N件物品和一个容量为V的背包,对于每一件物品给出该物品的体积价值和组别,由于每组的物品之间相互冲突,所以对于每组物品我们最多选择一件,求解将哪些物品装入背包可使体积总和不超过背包容量且价值最大;
也就是说我们可以从分组的角度来看,这其实是一个01背包问题,选或不选一个组的某一个物品:
对于分组背包我向大家推荐一种存储方式,这种方式让代码简洁易懂
我们在存储组数的时候可以开一个二维数组a[][],用a[i][0]来表示组别为i的物品的个数;
然后用a[i][j]来表示组别为i的第几的物品,
附上伪代码:
for k=所有的组数
for v=V...0;
for 所有的i属于k组的
f[v]=max(f[v],f[v-v[a[k][i]]]+val[a[k][i]]])
大家可以好好体会一下a[][]这个二维数组的巧妙。
阅读全文
0 0
- 背包问题总结(模板)
- 背包问题模板(01背包,完全背包,多重背包)
- 背包(01背包、完全背包、多重背包)问题总结
- 总结——背包问题解析及模板代码
- 多重背包问题(含模板)
- 部分背包问题模板
- 背包问题模板
- 背包问题_模板
- 简单背包问题模板
- 背包问题标准模板
- 背包问题模板
- 背包问题模板
- 背包问题模板
- 背包问题模板
- 01背包问题模板
- 多重背包问题模板
- 【51nod 1085】背包问题(0-1背包模板)
- 模板①:背包问题(0-1背包&完全背包&多重背包)
- 二维数组与双重指针
- Qt获取文件路径和文件名
- 技术类比较好的网站收集
- Kolla部署OpenStack失败问题(4)
- 【Grammar】in 和 within 用法和区别
- 背包问题总结(模板)
- 分享几个开源的框架
- 游戏服务器架构发展史
- 移植mypaint项目,在windows上实现毛笔字
- html5六人九人三公棋牌平台制作游戏框架cnGameJS开发实录
- 用sublime text 3 编译c++的配置过程
- 动态链接库的使用
- 华为交换机同一VLAN配置多个网段
- Android Studio R文件bug及解决方案