01背包
2016-01-15 20:47
267 查看
01背包问题:
一共有n个物品(每个物品只有一个),每个物品的体积为Vi,重量为Wi。在背包容量vol一定的条件下,装入物品,使得背包总重量最大。
分析:由于物品只有一个且放入无序,所以可以人为地将物品分阶段处理,即第一阶段只考虑第一件物品并假设背包容量从0-vol进行DP,第二个阶段只考虑前两件物品并假设背包容量从0-vol进行DP,以此类推,这样的话,可以保证每个阶段都得到最优解,且上一个阶段影响下一阶段的最优解,概括得出状态转移方程:d[i][j]=max(d[i-1][j],d[i-1][j-vi])
代码:
滚动数组:
其实,如果题目要求的输出非常简单,则可以不必存储除了最后一个阶段以外阶段的数据,并用滚动数组进行计算
分析:用以上方法计算时,状态转移的其中一种情况就是完全复制上一阶段的结果,所以我们假定当前阶段就满足这种状态转移,先将上一阶段的结果完全复制,再在当前阶段中判断是否真的满足这种情况,因此,我们可以只用一维数组来进行DP,节省了很多空间。其中从后往前进行DP的原因在于前面的结果可以影响后面的结果,但是后面的结果不能影响前面的结果,所以我们需要先计算后面的结果,而不用滚动数组时则不需考虑这个问题,从前往后或者从后往前都是一样的。同时,由于已经默认下一阶段复制到当前阶段,所以每个阶段仅需DP到假设的总空间大于或等于第i个物品的空间即可。
代码(直接把二维数组改为一维数组即可):
一共有n个物品(每个物品只有一个),每个物品的体积为Vi,重量为Wi。在背包容量vol一定的条件下,装入物品,使得背包总重量最大。
分析:由于物品只有一个且放入无序,所以可以人为地将物品分阶段处理,即第一阶段只考虑第一件物品并假设背包容量从0-vol进行DP,第二个阶段只考虑前两件物品并假设背包容量从0-vol进行DP,以此类推,这样的话,可以保证每个阶段都得到最优解,且上一个阶段影响下一阶段的最优解,概括得出状态转移方程:d[i][j]=max(d[i-1][j],d[i-1][j-vi])
代码:
#include<cstdio> #include<cstring> int dp[9680],str[100][100]; int max(int a, int b) { return a > b ? a : b; } int main() { int i, j, n,vol,v,w; while (scanf("%d%d",&vol,&n) != EOF) { memset(str, 0, sizeof str); for (i = 1;i <= n;i++) { scanf("%d%d", &v, &w); for (j = vol;j >= 0;j--) if(j>=v) str[i][j] = max(str[i - 1][j], str[i - 1][j - v] + w); } printf("%d\n", str[i-1][vol]); } return 0; }
滚动数组:
其实,如果题目要求的输出非常简单,则可以不必存储除了最后一个阶段以外阶段的数据,并用滚动数组进行计算
分析:用以上方法计算时,状态转移的其中一种情况就是完全复制上一阶段的结果,所以我们假定当前阶段就满足这种状态转移,先将上一阶段的结果完全复制,再在当前阶段中判断是否真的满足这种情况,因此,我们可以只用一维数组来进行DP,节省了很多空间。其中从后往前进行DP的原因在于前面的结果可以影响后面的结果,但是后面的结果不能影响前面的结果,所以我们需要先计算后面的结果,而不用滚动数组时则不需考虑这个问题,从前往后或者从后往前都是一样的。同时,由于已经默认下一阶段复制到当前阶段,所以每个阶段仅需DP到假设的总空间大于或等于第i个物品的空间即可。
代码(直接把二维数组改为一维数组即可):
<pre name="code" class="cpp">#include<cstring> int dp[9680],str[100]; int max(int a, int b) { return a > b ? a : b; } int main() { int i, j, n,vol,v,w; while (scanf("%d%d",&vol,&n) != EOF) { memset(str, 0, sizeof str); for (i = 1;i <= n;i++) { scanf("%d%d", &v, &w); for (j = vol;j >= v;j--) str[j] = max(str[j], str[j - v] + w); } printf("%d\n", str[vol]); } return 0; }
相关文章推荐
- 深入分析JavaWeb Item54 -- Spring中的AOP面向切面编程2
- 编程策略类note
- hbase异常:java.io.IOException: Unable to determine ZooKeeper ensemble
- 如何自己创建Servlet并配置web.xml
- 史上最全最经常使用的正則表達式-(基本够用值得收藏)
- Mysql Windows 发布多个实例
- Homework1-15
- 蓝桥杯-基础练习-十进制转十六进制
- 题目1019:简单计算器
- IOS 开发的官方文档链接
- iOS 多线程之GCD
- C++创建二叉树(一)
- 【应用】归并有序表
- 学习设计模式笔记
- [Android Pro] svn实例
- linux 挂载硬盘,创建新分区,删除分区
- Ubuntu升级到14.04
- ubuntu14.04 caffe配置中cudnn的配置
- HBase的javaAPI的增删改查的基本操作实现
- freemark如何判空容错