图片来源活动 - AcWing
有 N件物品和一个容量为 V 的背包,每件物品有各自的价值且能被选择无数次,要求在有限的背包容量下,装入的物品总价值最大。
一,暴力解法(容易超时)
#include<iostream>
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N][N];
int main(){
int n,m;
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=0;j<=m;j++){
for(int k=0;k*v[i]<=j;k++){
f[i][j]=max(f[i-1][j-k*v[i]]+w[i]*k,f[i][j]);
}
}
}
cout<<f[n][m]<<endl;
return 0;
}
二,二维版本
#include<iostream>
using namespace std;
const int N=1e3+10;
int a[N],b[N],dp[N][N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
for(int i=1;i<=n;i++){
for(int j=0;j<=m;j++){
dp[i][j]=dp[i-1][j];
if(j>=a[i])
dp[i][j]=max(dp[i][j],dp[i][j-a[i]]+b[i]);//与01背包相似不同点是01背包在第i-1层找最大值
} //而完全背包在第i层寻找最大值(因为完全背包每层可以选择多个)
}
cout<<dp[n][m]<<endl;
return 0;
}
三,一维版本(与01背包相似只是j的遍历方向不同)
#include<iostream>
using namespace std;
const int N=1e3+10;
int a[N],b[N],dp[N];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
for(int i=1;i<=n;i++){
for(int j=a[i];j<=m;j++){
dp[j]=max(dp[j],dp[j-a[i]]+b[i]); //背包容量是从大到小的因此j一定大于a[i]
}
}
cout<<dp[m]<<endl;
return 0;
}