代码原理:将多重背包问题转化为 01 背包问题的思路来求解在给定背包容量和若干物品(每个物品有不同数量的可选择份数、价值和体积)的情况下,能装入背包的最大价值
#include<bits/stdc++.h>
using namespace std;
int v,n;//v 表示背包容量,n表示物品的种类数。
long long w[20005],q[20005];//w用于存储价值,q数组用于存储体积
long long dp[400005];//动态规划中用于记录状态的数组
int main(){
cin>>n>>v;
int cnt=0;
for(int i=1;i<=n;i++){
int a,b,s;
cin>>a>>b>>s;
int k=1;
while(k<=s){
cnt++;
q[cnt]=a*k;
w[cnt]=b*k;
s-=k;
k*=2;
}
if(s>0){
cnt++;
q[cnt]=a*s;
w[cnt]=b*s;
}
/*
对于每一种物品,通过一个循环将该物品按照二进制拆分的思想进行处理。
把原本有 s 个的同一种物品,拆分成若干个不同 “数量” 的该物品
利用二进制的特性,比如拆分成 1 个、2 个、4 个……
这样的组合,能组合出任意小于等于 s 的数量情况
*/
}
for(int i=1;i<=cnt;i++){
for(int j=v;j>=q[i];j--){
if(j>=q[i])
dp[j]=max(dp[j-q[i]]+w[i],dp[j]); //动态规划
}
}
cout<<dp[v];
return 0;
}