背包问题
2015-12-11 21:54
232 查看
1.问题描述
假设有n件物品,分别编号为1, 2...n。其中编号为i的物品价值为vi,它的重量为wi。为了简化问题,假定价值和重量都是整数值。现在,假设有一个背包,它能够承载的重量是W。如何往包里装这些物品,使得包里装的物品价值最大化。用数学语言描述问题:
2.问题思路分析
我们知道分治法的核心是可以把问题不断分成更小的、更好解决的子问题,然后解决子问题,子问题再合成原问题。但是分治法如果分的子问题如果不独立的话,会在重复的求解共同的子问题。这个问题需要一种另一种思路-----动态规划。可以假设现在求解出了最优解,是1...k(k<n)个物体,对第i个物体,想象一下,如果说拿掉这个物体,剩下的部分针对W-w[i]是不是最优解?用反证法来证明一下,假设不是最优解,那么肯定存在更优的解,那这个更优的解加上我们拿掉的i物体,能够组成比我们求解出的最优解更优,与我们的假设是相违背的。因此,拿掉i物体,剩下的物体依然是W-w[i]的最优解。
在n个物体中,假设c[i][j](表示第i个物体,背包剩j的容量)是前i个物体的最优解,那么对第i+1个物体,只有两种情况;
情况1:拿,那么当前的价值为c[i][j]+v[i+1],达到第i+1的最优解;
情况2:不拿,最优解仍然为c[i][j],达到第i+1的最优解;
背包为空或者物体重量超过背包容量时,效益为0;
公式最终可归纳为:
注:对于初学者来说,一开始可能不好理解,建议看一下youtube上的对0-1背包解释的一个视频Dynamic
Programming:0/1 Knapsack Problem
3.实现
/******************************************* 0-1背包问题 作者:Andrewseu 日期:2015/12/11 *******************************************/ #include<iostream> #include<iomanip> using namespace std; int value[100];//benifit int weight[100];//weight int c[100][100]; void knapsack(int n,int w){ for (int i = 1; i <= n; ++i){ for (int j = 1; j <= w; ++j){ //若第i个物体加进来不超过背包总重量并且价值比之前大,则改变最优值,否则保持不变 if (weight[i] <= j && c[i - 1][j-weight[i]] + value[i] > c[i - 1][j]) c[i][j] = c[i - 1][j-weight[i]] + value[i]; else c[i][j] = c[i-1][j]; } } } int main(){ int n, w; cout << "Enter the number and weight:"; cin >> n >> w; for (int i = 1; i <= n; ++i){ cin >> weight[i]>>value[i]; } knapsack(n,w); for (int i = 1; i <= n; ++i){ for (int j = 1; j <= w; ++j){ cout << setw(6)<<c[i][j] << " "; } cout << endl; } return 0; }
测试输入:
n=4,W=5,weight{2,3,4,5},benefit{3,7,2,9}
输出:10
相关文章推荐
- 使用JAVA实现模拟登陆并发送新浪微博(非调用新浪API)
- NA summary笔记
- hdu 1081 to be max
- 大型网站架构演化历程
- 硬币找零问题,力求解决一些一切可能的办法,硬币的最小数量,有多少每个硬币的
- sql 时间函数用法
- PhotoView开源项目剖析
- java中的this与super的区别
- android stdio安装记录
- android 解码出来的视频frame数据,是如何一步步的传递到显示端的(使用 GPU offline 合成)
- linux c++ 利用timerfd和epoll封装计时器(Timer)类
- ubuntu下查看某个命令的方法
- 面向对象的特征有哪些方面
- 《利用python进行数据分析》读书笔记--第七章 数据规整化:清理、转换、合并、重塑(二)
- BZOJ1261: [SCOI2006]zh_tree
- idea远程调试linux下的tomcat
- [LeetCode]029-Divide Two Integers
- java泛型(三)、通配符的使用
- 阿里云ONS而微软Azure Service Bus体系结构和功能比较
- java泛型(二)、泛型的内部原理:类型擦除以及类型擦除带来的问题