多重背包_二进制优化
第一步:拆分
//二进制拆分
int num=1;//计数
int vv[10001],ww[10001];
for(int i=1;i<=n;i++){
cin>>v>>w>>s;//体积 价值 数量
for(int j=1;j<=s;j<<=1){
vv[num]=v*j;
ww[num++]=w*j;
s-=j;
}
//如果还有剩下 剩下的部分为一个 个体
if(s){
vv[num]=s*v;
ww[num++]w*s;
}
}
输入:
3 7
2 3 12
3 5 15
1 2 3
拆分结果
输出:
10 7
1:2 3
2:4 6
4:8 12
5:10 15
1:3 5
2:6 10
4:12 20
8:24 40
1:1 2
2:2 4
第二步
通过 01背包问题求解
for(i =1;i<num;i++){
for(j=m;j>=vv[i];j--){
dp[j]=max(dp[j],dp[j-vv[i]]+ww[i])
}
}
cout<<dp[m];
最终调试代码:
#include<iostream>
using namespace std;
int main(){
//二进制拆分
int dp[10001];
int n,m;
int v,w,s;
cin>>n>>m;
int num=1;//计数
int vv[10001],ww[10001];
for(int i=1;i<=n;i++){
cin>>v>>w>>s;//体积 价值 数量
for(int j=1;j<=s;j<<=1){
vv[num]=v*j;
ww[num++]=w*j;
s-=j;
}
//如果还有剩下 剩下的部分为一个 个体
if(s){
vv[num]=s*v;
ww[num++]=w*s;
}
}
//01背包
for(int i =1;i<num;i++){
for(int j=m;j>=vv[i];j--){
dp[j]=max(dp[j],dp[j-vv[i]]+ww[i]);
}
}
cout<<dp[m];
}
运行结果: