01背包问题分析
2015-09-03 19:59
225 查看
“背包题目”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,…,wn,希望从N件物品中选择若干物品,所选物品的重量之和恰能放进该背包,即所选物品的重量之和即是S。递归和非递归解法都能求得“背包题目”的一组解,试写出“背包题目”的非递归解法。
解法一:
最初思路就是动态规划,
动态规划求一组解,我们用f[i][j]用来表示前i件物品随意选择一些物品能够恰好装满容量为j的背包的可行性=1,不可行则为0,其中i指的是物品标号,j指的是背包的大小(0~S);如果j < v[i]:f[i][j] = f[i-1][j] ,表示第i个物品的重量已经超过最大重量j了,则结果变为了前i-1件物品能否恰好装入容量为j的背包的可行性即等于f[i-1][j];
如果j>=v[i],此时就可以选择装或者不装第i件物品了,如果装入,则它的可行性就变为了前i-1前物品是否能恰好装入j-vec[i]容量的背包中可行性了;选择不装,则它的可行性变为了前i-1物品能否恰好装入容量为j的背包中可行性了,两者有一个可行,表明前i件物品就能恰好装入容量为j的背包中。f[i][j] = f[i-1][j]||f[i-1][j-vec[i]]
初始化:f[i][0]=1(i=0,1,2,,..n) 其它的f[i][j]都等于0
找出最终的一组解,用回溯就可以了。如果存在可行解,那么f
[S]一定为1
主要公式为:
代码为:
另外值得注意的是:
动态规划的前提是我们的物体重量数组是排序的(由小到大),如果是随机的,我们仿真发现会有问题!!!!这用动态规划关键方程也可解释,j是由小到大的,我们的总重量是增量增加的。
解法一:
最初思路就是动态规划,
动态规划求一组解,我们用f[i][j]用来表示前i件物品随意选择一些物品能够恰好装满容量为j的背包的可行性=1,不可行则为0,其中i指的是物品标号,j指的是背包的大小(0~S);如果j < v[i]:f[i][j] = f[i-1][j] ,表示第i个物品的重量已经超过最大重量j了,则结果变为了前i-1件物品能否恰好装入容量为j的背包的可行性即等于f[i-1][j];
如果j>=v[i],此时就可以选择装或者不装第i件物品了,如果装入,则它的可行性就变为了前i-1前物品是否能恰好装入j-vec[i]容量的背包中可行性了;选择不装,则它的可行性变为了前i-1物品能否恰好装入容量为j的背包中可行性了,两者有一个可行,表明前i件物品就能恰好装入容量为j的背包中。f[i][j] = f[i-1][j]||f[i-1][j-vec[i]]
初始化:f[i][0]=1(i=0,1,2,,..n) 其它的f[i][j]都等于0
找出最终的一组解,用回溯就可以了。如果存在可行解,那么f
[S]一定为1
主要公式为:
代码为:
#include<iostream> #include<vector> using namespace std; vector<int> packageInteration(int weight[], int S,int n); void main() { int n=5; int weight[]={4,5,7,9,8}; int S=20; vector<int>res; res=packageInteration(weight,S,n); } vector<int> packageInteration(int weight[], int S,int n) { vector<vector<int>>f; vector<int> temp(S+1,0); for(int i=0;i<n+1;i++) { f.push_back(temp); } for(int i=0;i<n+1;i++) f[i][0]=1; for(int i=1;i<n+1;i++) { for(int j=1;j<S+1;j++) { if(j>=weight[i-1]) f[i][j]=(f[i-1][j]||f[i-1][j-weight[i-1]]);//注意!!!这里用的是i-1而不是i的原因是,我们物体重量的数组下标是从0开始的,f的0列和0行无意义,是从1开始的。所以差别对待。 else f[i][j]=f[i-1][j]; } } int j=S; vector<int> res; for(int i=n;i>0;i--) { if(j>=weight[i-1]) { if(f[i][j-weight[i-1]]==1) { res.push_back(i); j=j-weight[i-1]; } } } return res; }这种动态规划的详细分析在博客中有提及,区别是f[i][j]值由总价值变为可行性。http://blog.csdn.net/sinat_24520925/article/details/42920909
另外值得注意的是:
动态规划的前提是我们的物体重量数组是排序的(由小到大),如果是随机的,我们仿真发现会有问题!!!!这用动态规划关键方程也可解释,j是由小到大的,我们的总重量是增量增加的。
相关文章推荐
- 编写PHP扩展一:PHP与Zend介绍
- opencv轮廓提取与轮廓拟合
- 新手上道多多关照
- java注释
- usaco Subset Sums
- Java中父类强制转换为子类的可能
- C++基础---string类的operator+=/append/push_back
- 卡方检验文本特征选择
- java 重载与重写
- 机器视觉,高速拍照,工业相机开发大阅兵,一场视觉的盛宴
- plist文件操作
- RelativeLayout相对布局
- C++基础---string类的replace
- hdu1059
- Android(java)学习笔记208:Android中操作JSON数据(Json和Jsonarray)
- 加速vps
- 从零开始学 iOS 开发的15条建议
- JavaScript之取消计时器clearTimeout()
- oracle中的分区表
- 作为程序员最应该投资的是这十件事