一、采药 (01背包)
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][N];
int w[N],v[N];
int main(){
int t,m;
cin>>t>>m;
for(int i=1;i<=m;i++) cin>>v[i]>>w[i];
for(int i=1;i<=m;i++){
for(int j=0;j<=t;j++){
f[i][j]=f[i-1][j];
if(j-v[i]>=0) f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
}
}
cout<<f[m][t];
return 0;
}
二、完全背包
(1)暴力
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N][N];
int w[N],v[N];
int main(){
int t,m;
cin>>t>>m;
for(int i=1;i<=m;i++) cin>>v[i]>>w[i];
for(int i=1;i<=m;i++){
for(int j=0;j<=t;j++){
for(int k=0;k*v[i]<=j;k++){
f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
}
}
cout<<f[m][t];
return 0;
}
(2) 优化
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
int f[N];
int w[N],v[N];
int main(){
int t,m;
cin>>t>>m;
for(int i=1;i<=m;i++) cin>>v[i]>>w[i];
for(int i=1;i<=m;i++){
for(int j=v[i];j<=t;j++){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[t];
return 0;
}
三、多重背包
(1) 暴力
#include <bits/stdc++.h>
using namespace std;
const int N=1010;
const int INF=0x3f3f3f3f;
int f[N][N];
int w[N],v[N],s[N];
int main(){
int t,m;
cin>>t>>m;
for(int i=1;i<=m;i++) {
cin>>v[i]>>w[i]>>s[i];
if(s[i]==0) s[i]=INF;
}
for(int i=1;i<=m;i++){
for(int j=0;j<=t;j++){
for(int k=0;k*v[i]<=j&&k<=s[i];k++){
f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+w[i]*k);
}
}
}
cout<<f[m][t];
return 0;
}
(2) 二进制优化版
设s为物品可取次数,则s可表达为
这里
#include <bits/stdc++.h>
using namespace std;
const int N=24010;
int f[N];
int w[N],v[N]; //w[]为价值,v[]为体积
int main(){
int t,m;
cin>>m>>t; //m为物品种数,t为背包容量
int cnt=0;
for(int i=1;i<=m;i++) {
int a,b,s;
cin>>a>>b>>s; //a为体积,b为价值,s为个数
int k=1;
while(k<=s){
cnt++;
w[cnt]=k*b;
v[cnt]=k*a;
s-=k;
k*=2;
}
if(s>0){
cnt++;
w[cnt]=s*b;
v[cnt]=s*a;
}
}
m=cnt;
for(int i=1;i<=m;i++){
for(int j=t;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[t];
return 0;
}
为数组容量
四、分组背包
#include <bits/stdc++.h>
using namespace std;
const int N=110;
int f[N];
int w[N][N],v[N][N];
int s[N];
int main(){
int n,m;
cin>>n>>m; //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(v[i][k]<=j) f[j]=max(f[j],f[j-v[i][k]]+w[i][k]);
}
}
}
cout<<f[m];
return 0;
}