1. 程式人生 > >多重背包(二進制拆分法)

多重背包(二進制拆分法)

ont mage lse alt 之前 sub -- div .com

眾所周知,從20 ,21,...,2k-1這k個2的整數次冪中選出若幹相加,可以表示出0~2k-1之前的任意整數

技術分享圖片

所以我可以把Ci個物品分解成p+2個

即若幹個2的冪次方為系數的體積(對下面的這些體積進行0/1背包)

20*Vi+...+2p*Vi+Ri*Vi

for(int i=1;i<=n;i++){//種類數
            int temp=c[i]; int now=1;
            while(1){    //把c[i]拆解成若幹個2的冪次方 
                if(temp>now){
                    temp
-=now; for(int j=m;j>=now*a[i];j--) if(dp[j-now*a[i]]) dp[j]=1; now*=2; }else{ for(int j=m;j>=temp*a[i];j--) if(dp[j-temp*a[i]]) dp[j]
=1; break; } } }

多重背包(二進制拆分法)