5. 多重背包问题 II ______二进制转换!!!精妙
作者:
cyuyu
,
2022-03-12 17:57:12
,
所有人可见
,
阅读 181
二进制
s可以用二进制来表示,根据一个数的二进制特点,如:1111,前三位的和为(1+2+4)=7等于第四位数值这一特性和
k=logs
1 ~ s可以用1,2,3,4……,2^k,c表示,c一定小于2^(k+1) - 1
1,2,3,4,……,2^k的和为2^k+1 - 1 = sum,所以c一定小于2^(k+1) - 1, s=sum+c
代码:
#include<iostream>
using namespace std;
const int N=25000;//N*w!!!!
int v[N],w[N];
int f[N];
int main(){
int m,n;
cin>>m>>n;
int a,b,s;
int cnt=0;
for(int i=1;i<=m;i++){
cin>>a>>b>>s;
int k=1;
while(k<=s){
cnt++;
v[cnt]=a*k;
w[cnt]=b*k;
s=s-k;
k=k*2;
}
if(s>0){
cnt++;
v[cnt]=s*a;
w[cnt]=s*b;
}
}
m=cnt;
for(int i=1;i<=m;i++){
for(int j=n;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[n]<<endl;
return 0;
}