目录
01背包问题
递归做法
递推做法(二维)
递推做法(一维)
完全背包问题
递归做法
递推做法
01背包问题
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
递归做法
#include
using namespace std;
int N,V;
int v[1010],w[1010],d[1010][1010];
int dp(int i,int j){
if(d[i][j]) return d[i][j];
if(i>N) return 0;
if(j-v[i]>=0) d[i][j]=max(dp(i+1,j-v[i])+w[i],dp(i+1,j));
else d[i][j]=dp(i+1,j);
return d[i][j];
}
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++)
cin >> v[i] >> w[i];
cout << dp(1,V);
return 0;
}
递推做法(二维)
#include
using namespace std;
int N,V;
int v[1010],w[1010],d[1010][1010];
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++)
cin >> v[i] >> w[i];
memset(d,0,sizeof(d));
for(int i=1;i<=N;i++){
for(int j=1;j<=V;j++){
if(j-v[i]>=0)
d[i][j]=max(d[i-1][j-v[i]]+w[i],d[i-1][j]);
else
d[i][j]=d[i-1][j];
}
}
cout << d[N][V];
return 0;
}
递推做法(一维)
#include
using namespace std;
int N=0,V,n=0;
int v[10010],w[10010],d[10100]={0};
int main(){
cin >> n >> V;
for(int i=1;i<=n;i++){
int vi,wi,si;
cin >> vi >> wi >> si;
for(int j=1;j<=si;j++){
N++;
v[N]=vi;
w[N]=wi;
}
}
for(int i=1;i<=N;i++)
for(int j=V;j>=v[i];j--)
d[j]=max(d[j],d[j-v[i]]+w[i]);
cout << d[V] << endl;
return 0;
}
完全背包问题
#includeusing namespace std; int N,V; int v[1010],w[1010],d[1010][1010]; int main(){ cin >> N >> V; for(int i=1;i<=N;i++) cin >> v[i] >> w[i]; memset(d,0,sizeof(d)); for(int i=1;i<=N;i++){ for(int j=1;j<=V;j++){ if(j-v[i]>=0) d[i][j]=max(d[i-1][j-v[i]]+w[i],d[i-1][j]); else d[i][j]=d[i-1][j]; } } cout << d[N][V]; return 0; }
递推做法(一维)
#include
using namespace std;
int N=0,V,n=0;
int v[10010],w[10010],d[10100]={0};
int main(){
cin >> n >> V;
for(int i=1;i<=n;i++){
int vi,wi,si;
cin >> vi >> wi >> si;
for(int j=1;j<=si;j++){
N++;
v[N]=vi;
w[N]=wi;
}
}
for(int i=1;i<=N;i++)
for(int j=V;j>=v[i];j--)
d[j]=max(d[j],d[j-v[i]]+w[i]);
cout << d[V] << endl;
return 0;
}
完全背包问题
有 N 件物品和一个容量是 V 的背包。每种物品都有无限件可用。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
递归做法
#include
using namespace std;
int N,V;
int v[1010],w[1010],d[1010]={0};
int dp(int m){
if(d[m]) return d[m];
for(int i=1;i<=N;i++){
if(m-v[i]>=0) d[m]=max(d[m],dp(m-v[i])+w[i]);
}
return d[m];
}
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++)
cin >> v[i] >> w[i];
cout << dp(V);
return 0;
}
递推做法
#include
using namespace std;
int N,V;
int v[1010],w[1010],d[1010];
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++)
cin >> v[i] >> w[i];
memset(d,0,sizeof(d));
for(int i=1;i<=V;i++){
int maxw=0;
for(int j=1;j<=N;j++){
if(i-v[j]>=0) maxw=max(maxw,d[i-v[j]]+w[j]);
}
d[i]=maxw;
}
cout << d[V];
return 0;
}
#includeusing namespace std; int N,V; int v[1010],w[1010],d[1010]; int main(){ cin >> N >> V; for(int i=1;i<=N;i++) cin >> v[i] >> w[i]; memset(d,0,sizeof(d)); for(int i=1;i<=V;i++){ int maxw=0; for(int j=1;j<=N;j++){ if(i-v[j]>=0) maxw=max(maxw,d[i-v[j]]+w[j]); } d[i]=maxw; } cout << d[V]; return 0; }



