图片来源活动 - 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;
}