题目:P1776
思路
多重背包和0-1背包的差别就是0-1背包里一个物品只有一件,但多重背包里一个物品有s[i]件
那怎么做呢?
我们分情况讨论:
1.s[i]*w[i]>=m 转完全背包
2.否则转0-1背包。怎么转呢?拿一个k去枚举数量,于是问题变成了一个重量为k*w,价值为k*v的物品取不取
来人!上代码!
#include <bits/stdc++.h>
using namespace std;
int w[maxn],v[maxn],s[maxn],dp[maxm];
int main(){
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>w[i]>>v[i]>>s[i];
for(int i=1;i<=n;i++){
if(s[i]*w[i]>=m){//相当于完全背包(因为比背包容量m大)
for(int j=w[i];j<=m;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
else{//否则转0-1背包
for(int j=m;j>=w[i];j--){
for(int k=s[i];k>=0;k--){//枚举数量
if(j>=k*w[i])
dp[j]=max(dp[j],dp[j-k*w[i]]+k*v[i]);
}
}
}
}
cout<<dp[m]<<endl;
return 0;
}
友情提醒:请不要Ctrl C+Ctrl V,这段代码有问题
显而易见,这玩意时间复杂度特别特别特别特别高。
所以我们要进行优化。
由于上篇博客说好了下期填一下完全背包的坑,所以我将在下下期和下下下期讲解如何优化。