題意:有權值分別為1,2,3,4,5,6的大理石,每種都有若干塊,能否把它們分成權值相等的2份。大理石的總數量不超過20000。(多重揹包)
分析:判斷dp[ v/2 ] ==v/2 即可,但過程如果用普通做法會超時,即多重揹包當成01揹包做效率很低,這時候要用二進位制拆分優化,將複雜度變為
二進位制拆分原理:
這裡是指乙個大數11101111 ,只要每一位上的1我們都有乙個數,就可以表示出來這個大數 也就是用1 2 4 8 (1 10 100 1000..) 可以表示出任意的數 ,那麼任意乙個數都可以經過處理變為2進製的數,為了方便每個二進位制的數只有乙個,這個處理可以看作把13 分為 1、2、4、6 (最後乙個6是為了處理方便避免重複) 。
二進位制拆分:
for(int i=1;i<=n;i++)view codeif(num[i])//
判斷是否會有餘下的部分.
//就好像我們某一件物品為13,顯然拆成二進位制為1,2,4.
//我們餘出來的部分為6,所以需要再來乙份.
}
code:
#include#includeview code#include
#include
#define inf 0x3f3f3f3f
using
namespace
std;
const
int maxn=120012
;int
n,v;
intdp[maxn];
int a[7
];int
v[maxn],w[maxn];
intmain()
if(v&1
)
else
if(a[i]!=0
) }
//printf("tot=%d\n",tot);
for(int i=0;i)
}//for(int i=6;i>=1;i--)//}
//}
if(dp[v/2]==v/2
) printf(
"can be divided.\n\n");
else
printf(
"can't be divided.\n\n");}}
return0;
}
POJ1014 多重揹包(二進位制拆分)
題目鏈結 題目大意 給出6個數,分別代表價值為1 6的6種物品的數量,求能否在價值相同的情況下平分這些物品。思路 多重揹包。一開始拆成01揹包來做,寫了三層迴圈,很顯然結果tle了。後來上網看了一下題解,大致意思是把每一種物品的數量拆成1,2,4,8,這樣的2的n次方數,比如將12拆成1,2,4,5...
多重揹包(二進位制拆分優化)
多重揹包基本模型如下 給定n種物品,其中第i種物品的體積為vi,價值為wi,並且有ci個。有一容積為m的揹包,要求選擇若干個物品放入揹包,使得物品總體積不超過m的前提下,物品價值總和最大。輸入格式 第一行兩個整數,n,m,用空格隔開,分別表示物品種數和揹包容積。接下來有 n 行,每行三個整數 vi,...
多重揹包的二進位制拆分法
在多重揹包的直接拆分法中,個數為 c i 的物體被拆成 c i 種不同的物體 這樣就使得物體的種類增加了很多,使得演算法效率很低。上述方法把 c i 拆成 c i 個1,於是任意選擇可以表示出 1 到 c i 之間的所有數,從而達到多重揹包的目的 想到,從 2 0,2 1,2 2,2 k 任意選擇可...