# 01背包、完全背包、多重背包问题分析

1. 01背包（ZeroOnePack）: 有n件物品和一个容量为m的背包。（每种物品均只有一件）第i件物品的费用是weight[i]，价值是value[i]。求解将哪些物品装入背包可使价值总和最大。

if(weight[n]>m)
return recursion(weight,value,m,n-1);
else
return max(recursion(weight,value,m,n-1),recursion(weight,value,m-weight[n],n-1)+value[n]);

if(weight[j]<=i){
res[i][j]=max(res[i][j-1],res[i-weight[j]][j-1]+value[j]);}
else
res[i][j]=res[i][j-1];

DP程序源码：

#include <iostream>
#include <vector>
using namespace std;
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
vector< vector<int> > res(m+1);
for(int i=0;i<m+1;++i)
res[i].resize(n+1);
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
if(i==0||j==0){
res[i][j]=0;
continue;
}
if(weight[j]<=i){
res[i][j]=max(res[i][j-1],res[i-weight[j]][j-1]+value[j]);
}
else
res[i][j]=res[i][j-1];
}
}
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
cout<<res[i][j]<<" ";
}
cout<<endl;
}
return 0;
}

#include <iostream>
#include <vector>
using namespace std;
int recursion(vector<int>& weight,vector<int>& value,int m,int n){
if(m==0||n==0)
return 0;
if(weight[n]>m)
return recursion(weight,value,m,n-1);
else
return max(recursion(weight,value,m,n-1),recursion(weight,value,m-weight[n],n-1)+value[n]);
}
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
cout<<recursion(weight,value,m,n)<<endl;
return 0;
}

m=10;
n=5;
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};

2. 完全背包(CompletePack): 有N种物品和一个容量为V的背包，每种物品都有无限件可用。第i种物品的费用是c[i]，价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量，且价值总和最大。

DP方法程序源码：

#include <iostream>
#include <vector>
using namespace std;
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
vector< vector<int> > res(m+1);
for(int i=0;i<m+1;++i)
res[i].resize(n+1);
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
if(i==0||j==0){
res[i][j]=0;
continue;
}
if(weight[j]<=i){
res[i][j]=max(res[i][j-1],res[i-weight[j]][j]+value[j]);
}
else
res[i][j]=res[i][j-1];
}
}
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
cout<<res[i][j]<<" ";
}
cout<<endl;
}
return 0;
}

#include <iostream>
#include <vector>
using namespace std;
int recursion(vector<int>& weight,vector<int>& value,int m,int n){
if(m==0||n==0)
return 0;
if(weight[n]>m)
return recursion(weight,value,m,n-1);
else
return max(recursion(weight,value,m,n-1),recursion(weight,value,m-weight[n],n)+value[n]);
}
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
cout<<recursion(weight,value,m,n)<<endl;
return 0;
}

3. 多重背包(MultiplePack): 有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用，每件费用是c[i]，价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量，且价值总和最大。

DP方法程序源码：

#include <iostream>
#include <vector>
using namespace std;
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
vector<int> size(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
int array3[6]={0,1,1,4,5,1};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
for(int i=1;i<n+1;++i){
//cin>>size[i];
size[i]=array3[i];
}
vector< vector<int> > res(m+1);
for(int i=0;i<m+1;++i)
res[i].resize(n+1);
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
if(i==0||j==0){
res[i][j]=0;
continue;
}
if(weight[j]<=i){
int numOfValue=min(i/weight[j],size[j]);
int maxValue=0;
for(int k=0;k<=numOfValue;++k){
int temp=res[i-weight[j]*k][j-1]+value[j]*k;
maxValue=max(maxValue,temp);
}
res[i][j]=maxValue;
}
else
res[i][j]=res[i][j-1];
}
}
for(int i=0;i<m+1;++i){
for(int j=0;j<n+1;++j){
cout<<res[i][j]<<" ";
}
cout<<endl;
}
return 0;
}

#include <iostream>
#include <vector>
using namespace std;
int recursion(vector<int>& weight,vector<int>& value,vector<int>& size,int m,int n){
if(m==0||n==0)
return 0;
if(weight[n]>m)
return recursion(weight,value,size,m,n-1);
else
{
int numOfValue=min(m/weight[n],size[n]);
int maxValue=0;
for(int i=0;i<=numOfValue;++i){
int temp=recursion(weight,value,size,m-weight[n]*i,n-1)+value[n]*i;
maxValue=max(maxValue,temp);
}
return maxValue;
}
}
int main(){
int m,n;
//cin>>m>>n;
m=10;
n=5;
vector<int> weight(n+1,0);
vector<int> value(n+1,0);
vector<int> size(n+1,0);
int array1[6]={0,2,2,6,5,4};
int array2[6]={0,6,3,5,4,6};
int array3[6]={0,1,1,4,5,1};
for(int i=1;i<n+1;++i){
//cin>>weight[i];
weight[i]=array1[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
value[i]=array2[i];
}
for(int i=1;i<n+1;++i){
//cin>>value[i];
size[i]=array3[i];
}
cout<<recursion(weight,value,size,m,n)<<endl;
return 0;
}

#### 几道有关钱币的背包问题分析

2016年04月05日 34KB 下载

#### 01背包，完全背包，多重背包的个人总结

2016-04-20 22:08:53

#### 史上最易懂的01背包，完全背包，多重背包讲解

2016-08-17 14:02:35

#### 经典背包问题----（01背包、完全背包、多重背包）

2017-10-31 19:34:33

#### 01背包模板、完全背包 and 多重背包（模板）

2014-06-21 09:41:03

#### 经典背包问题 01背包+完全背包+多重背包

2013-04-06 20:27:01

#### 背包问题详解：01背包、完全背包、多重背包

2017-03-17 11:47:48

#### 01背包 ,完全背包,多重背包 dp (动态规划入门dp)

2017-04-12 22:44:42

#### 多重背包转换成完全背包和01背包

2014-07-21 21:46:20

#### HDU2602/HDU1114/HDU2191(重新整理一下01背包，完全背包，多重背包)

2017-01-11 13:24:03