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

217人阅读 评论(0)

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;
}

1
0

* 以上用户言论只代表其个人观点，不代表CSDN网站的观点或立场
个人资料
• 访问：30560次
• 积分：1127
• 等级：
• 排名：千里之外
• 原创：72篇
• 转载：36篇
• 译文：0篇
• 评论：0条
评论排行