优化思路:
如果你知道了多重背包问题可以将x个相同物体分为单个,再一个一个判断拿与不拿,变成了01背包问题,那么这个二进制优化就简单了,你可以理解为一个一个拿太慢,但一堆一堆拿比较快,拿怎么一堆一堆的拿呢?设x个相同物体,一个一个判断拿与不拿就得到最优解,然而这个最优解一定小于等于x大于等于0;慢慢加一一个一个从0到x判断找到最优解的,但我们一堆一堆找效果也一样,比如1,2,4,8,从2的0次方到2的三次方;可以取到0到2的四次方减一也就是0到15的任意数,为什么呢?你把15转换为2进制是1111是四位,8是1000,4是100,2是10,1是1;它们几任意组合就可以使这四位任意位置为1或0,那么0到15的任意数是不是也能组合出来呢,现在我们来看看,如果最佳数是15,一个一个加是15次,但用二进制只需4次,这时间,不就优化出来了吗?
代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
int x[90000],y[90000];
int main()
{
int a,b,c,d,e,f,h,i;
scanf("%d %d",&a,&b);
int z[b+1];
memset(z,0,sizeof(z));
int g=0;
while(a--)
{
f=1;
scanf("%d %d %d",&c,&d,&e);
while(f<=e)
{
x[g]=c*f; //这里直接将分成堆的价值和体积存起来;
y[g]=d*f;
e=e-f;
f=f*2;
g++;
}
if(e>0)
{
x[g]=c*e;
y[g]=d*e;
g++;
}
}
f=g;
for(h=0;h<g;h++)
for(i=b;i>=x[h];i--) //转化成01背包问题拿哪一堆了
{
z[i]=fmax(z[i],y[h]+z[i-x[h]]);
}
printf("%d",z[b]);
}