DP背包小结(2)(结构完整,内容简洁,状态方程篇)
来源:互联网 发布:php 3des加密 编辑:程序博客网 时间:2024/04/30 06:50
0 背包小结2,以下状态转移代码,假设所有相关变量及数组都已初始化,物品对应体积和价值都从下标为1的数组开始存储,dp[]或者dp[][]是各个状态下的背包内所装物品总价值。
对于下面用到完全背包模型的,都可以预先进行一步优化,筛选掉所有满足volume[i]<volume[j]&&value[i]>value[j]的i和j物品,对于随机生成的数据来说,可以删掉很多不符合的物品。
1 01背包(背包总容纳bag,有type种物品,每种物品只有一个选择放还是不放,给出对应体积vlume[i]、对应价值value[i])
1)二维数组(建议充分理解,而不用之做题)(因为容易忘记将因体积原因放不进去的状态赋值,以及最后遍历v:0->bag寻找最大值)
//01背包 二维数组for(int i=1;i<=type;i++){ for(int j=0;j<=bag;j++){if(j>=volume[i]){dp[i][j]=max(dp[i-1][j],dp[i-1][j-volume[i]]+value[i]);}else{dp[i][j]=dp[i-1][j];//注意}} } int maxx=0; for(int j=1;j<=bag;j++){ maxx=max(maxx,dp[type][j]); }
//dp[i][j]指选择完第i个物品放或不放后 背包容量为j时,背包内所有物品的价值
//二维数组因为不能像一维数组一样自动更新,所以如果第i个物品装不进去时,要使dp[i][j]继承上一个物品放置之后的状态dp[i-1][j]而不是维持初始值。
2)一维数组
//01背包 一维数组for(int i=1;i<=type;i++){for(int j=bag;j>=volume[i];j--){dp[j]=max(dp[j],dp[j-volume[i]]+value[i]);}}//01背包,每种物品只有一个,该种物品的值不叠加,所以倒序,详见上一篇博客 DP背包问题小结(01背包,完全背包,需恰好装满或不需,一维DP、二维DP)
HDU2602 裸01背包
2 完全背包(背包总容纳bag,有type种物品,每种物品有无限多,给出对应体积vlume[i]、对应价值value[i])
//完全背包 一维数组for(int i=1;i<=type;i++){ for(int j=volume[i];j<=bag;j++){dp[j]=max(dp[j],dp[j-volume[i]]+value[i]);}}//完全背包,每种物品无限多个,该种物品的值可以叠加,所以直接正序,详见上一篇博客 DP背包问题小结(01背包,完全背包,需恰好装满或不需,一维DP、二维DP)
HDU4508 裸完全背包
3 多重背包
①耗用更多内存,来换取更快的时间:
(背包总容纳cash,有n种物品,每种物品有给定数量species[i].num,每种物品有给定的价值species[i].deno,这里物品的体积等同于价值。)
(使用的number[j]是指,第i个物品在当前的背包内存储金额j的情况下使用的数量,正是这个数组的使用来做到用空间换时间)
for(int i=0;i<n;i++){ memset(number,0,sizeof(number)); for(int j=species[i].deno;j<=cash;j++){ if(dp[j]<dp[j-species[i].deno]+species[i].deno&&number[j-species[i].deno]+1<=species[i].num){ dp[j]=dp[j-species[i].deno]+species[i].deno; number[j]=number[j-species[i].deno]+1; } } }
②耗用更多时间,来换取更少内存使用:
(背包总容纳bag,有type种物品,每种物品有给定的数量,给出对应体积vlume[i]、对应价值value[i]、对应数量number[i])
注意!倒序!
以下两者都是利用倒序 每一种物品都只放一个的特性,前者是该类物品放k次每次都放一个,后者是该类物品放一次 一次从1到k 放入个数依次增大
//多重背包,一维数组for(int i=1;i<=type;i++){int minn=min(number[i],bag/volume[i]);//这里for(int k=1;k<=minn;k++){for(int j=bag;j>=volume[i];j--){//注意是倒序,否则就错了dp[j]=max(dp[j],dp[j-volume[i]]+value[i]);}}}
(POJ1276找零钱)
//防止给出的该类物品个数大于实际上能存储的该类物品最大数量(有些用母函数的代码,就是在这里判断一步,如果给出的数量大于背包总容量除以该类物品体积得到的数量,那么就认为该类物品是取不完的 可以转化为完全背包来做,否则就转化为01背包)
OR
for(int i=1;i<=type;i++){for(int j=bag;j>=volume[i];j--){//注意是倒序,否则就错了for(int k=1;k<=number[i]&&(volume[i]*k<=j);k++){//k=0开始就是不放等同于dp[j],所以不用从0开始dp[j]=max(dp[j],dp[j-volume[i]*k]+value[i]*k);}} }HDU2191 裸多重背包
4二维费用的背包问题 (隐晦表示二维费用背包:有时候题目交代背包最多存x件物品,这是隐晦地表示背包能存件数也是一种费用。)(加多重背包的,类似,加数量那一步循环)
//二维费用背包(两种代价) 完全背包(每种物品无限多个)——所以正序for(int i=1;i<=type;i++){ for(int j=volume[i];i<=bag_volume;i++){ for(int l=weight[i];l<=bag_weight;l++){ dp[j][l]=max(dp[j][l],dp[j-volume[i]][l-weight[i]]+value[i]); } }}
OR
//二维费用背包(两种代价) 01背包(每种物品只有一个)——所以倒序for(int i=1;i<=type;i++){ for(int j=bag_volume;j>=volume[i];j--){ for(int l=bag_weight;l>=weight[i];l--){ dp[j][l]=max(dp[j][l],dp[j-volume[i]][l-weight[i]]+value[i]); } }}
HDU2159 裸二维背包
5混合背包
看情况组合,部分多重背包在数量足够的情况下可以转化为完全背包,而完全背包又可以转为01背包处理
HDU3591混合背包-经典
6分组背包
7有依赖背包
8泛化物品
9部分算法优化以及背包问题问法变化
1)二进制优化
//注意,number[i]已被改动,如果不想原来的数组里改动,可以另存一个数组里、参考下面给出例题的解题报告。for(int i=1;i<=n;i++){ for(int k=1;k<=number[i];k*=2){ for(int j=bag;j>=volume[i]*k;j--){ dp[j]=max(dp[j],dp[j-volume[i]*k]+k); } number[i]-=k;//!!! } for(int j=bag;j>=volume[i]*number[i];j--){ dp[j]=max(dp[j],dp[j-volume[i]*number[i]+number[i]); }}HDU3591混合背包-经典
剩下的再写、
对应题目,请参考本博客DP一类下有关背包的题目。
(本文内容结构参考了dd大牛《背包九讲》,链接之一,http://www.cnblogs.com/jbelial/articles/2116074.html)(注意里面有小错误)
- DP背包小结(2)(结构完整,内容简洁,状态方程篇)
- 01背包状态方程详解
- 01背包多种状态方程
- 背包dp小结
- 01背包最佳写法(最简洁)
- 网页优化内容需要内容全面、标题简洁突出重点、内容结构整洁
- 01背包(DP)
- hdu2955 dp(背包)
- Coins(背包DP)
- poj3211(背包dp)
- Birthday (背包dp)
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- 0-1背包问题入门小结 动态规划(DP)经典题目 POJ324 POJ1276
- DP背包问题小结(01背包,完全背包,需恰好装满或不需,一维DP、二维DP)
- 01背包、完全背包(DP)
- DP总结(1) 01背包 完全背包 多重背包
- HDOJ-4276(树形DP+背包DP)
- Linux下数据库MYSQL忘记登录密码及更换密码的解决办法
- 网易互娱2017实习生招聘游戏研发工程师在线笔试第二场(图像处理)
- hdu 1078
- Linux查看系统开机时间
- CF-187A-Permutations
- DP背包小结(2)(结构完整,内容简洁,状态方程篇)
- 阶乘的精确值&大数阶乘
- mac sublime2-3 text 安装 emmet Html 开发神器 react
- OpenCV249+Eigen+VS2010属性表配置
- [剑指offer]旋转数组的最小值
- Ubutu Mosquitto部署和相关的配置(支持websocket)
- EM算法(Expectation Maximization Algorithm )
- AS基本使用总结之从svn导入eclipseADT项目
- PrintDirectoryFiles