目录
01背包问题
有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。
第 i 件物品的体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
输出最大价值。
递归做法
#include<bits/stdc++.h>
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<bits/stdc++.h>
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<bits/stdc++.h>
using namespace std;
int N,V;
int v[10010],w[10010],d[10010]={0};
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++)
cin >> v[i] >> w[i];
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<bits/stdc++.h>
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<bits/stdc++.h>
using namespace std;
int N,V;
int v[1010],w[1010],d[1010]={0};
int main(){
cin >> N >> V;
for(int i=1;i<=N;i++) cin >> v[i] >> w[i];
for(int i=1;i<=V;i++)
for(int j=1;j<=N;j++)
if(i-v[j]>=0) d[i]=max(d[i],d[i-v[j]]+w[j]);
cout << d[V];
return 0;
}