1、01背包问题
暴力做法
#include <iostream>
using namespace std;
const int N = 1100;
int n,m;
int v[N],w[N];
int f[N][N];
int main(){
cin>>n>>m; // n代表4个物品,m代表背包容量是5
for(int i = 1; i <= n; i ++) cin>>v[i]>>w[i];
// i 代表前i个物品,j代表所占体积不超过j
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j ++){
f[i][j] = f[i-1][j];
if(j >= v[i]) f[i][j] = max(f[i][j], f[i-1][j-v[i]] + w[i]);
}
}
cout<<f[n][m];
}
一维优化版本
#include <iostream>
using namespace std;
const int N = 1100;
int n,m;
int v[N],w[N];
int f[N];
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i ++) cin>>v[i]>>w[i];
for(int i = 1; i <= n; i++)
for(int j = m; j >= v[i]; j--)
f[j] = max(f[j], f[j-v[i]] + w[i]);
cout<<f[m];
}
2、完全背包问题
#include <iostream>
using namespace std;
const int N = 1100;
int n,m;
int v[N],w[N];
int f[N][N];
int g[N];
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i ++) cin>>v[i]>>w[i];
/* 二维写法
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j ++){
f[i][j] = f[i-1][j];
if(j>=v[i]) f[i][j] = max(f[i][j],f[i][j-v[i]] + w[i]);
}
}
cout<<f[n][m];
*/
// 优化减少一维
for(int i = 1; i <= n; i++){
for(int j = v[i]; j <= m; j ++){
g[j] = max(g[j],g[j-v[i]] + w[i]);
}
}
cout<<g[m];
}
3、多重背包
暴力做法
#include <iostream>
using namespace std;
const int N = 110;
int n,m;
int v[N],w[N],s[N];
int f[N][N];
int g[N];
int main(){
cin>>n>>m;
for(int i = 1; i <= n; i ++) cin>>v[i]>>w[i]>>s[i];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j ++){
for(int k = 0; k <=s[i] && k*v[i] <= j; k++){
f[i][j] = max(f[i][j],f[i-1][j-k*v[i]] + k*w[i]);
}
}
}
cout<<f[n][m];
}
优化版本:把s[i]拆成多个物品
#include<iostream>
using namespace std;
const int N = 22000, V = 22000;
int v[V],w[V];
int f[N];
int n,m;
int main(){
cin>>n>>m;
int cnt = 1;
while(n--){
int a,b,c;
cin>>a>>b>>c;
int k = 1;
while(k <= c){
v[cnt] = a*k;
w[cnt] = b*k;
cnt++;
c -= k;
k *= 2;
}
if(c){
v[cnt] = c*a;
w[cnt] = c*b;
cnt++;
}
}
n = cnt;
for(int i = 1; i <= n; i++)
for(int j = m; j >= v[i]; j--)
f[j] = max(f[j], f[j-v[i]] +w[i]);
cout<<f[m]<<endl;
}
4、分组背包问题
#include <iostream>
using namespace std;
const int N = 110;
int n,m;
int v[N][N],w[N][N];
int f[N],s[N];
int main(){
cin>>n>>m;
for(int i = 1; i<=n; i++){
cin>>s[i];
for(int j = 0; j < s[i]; j++)
cin>>v[i][j]>>w[i][j];
}
for(int i = 1; i <=n; i++)
for(int j = m; j >= 0; j--)
for(int k = 0; k < s[i]; k++)
if(j>=v[i][k])
f[j] = max(f[j],f[j-v[i][k]] + w[i][k]);
cout<<f[m]<<endl;
return 0;
}