多重揹包問題的二進位制優化

2021-10-03 07:15:03 字數 1717 閱讀 9564

前情提要:動態規劃——揹包問題——多重揹包問題

多重揹包問題

有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。

這題目和完全揹包問題很類似,特點是:每種物品都有自己特異的件數、花費、價值。

樸素演算法:

每種物品有n[i]件可以取用,需要列舉每種物品選了多少件(列舉件數不能超過揹包容量)

for

(int i=

1;i<=n;i++

)for

(int j=

0;j<=m;j++

)for

(int k=

0;k<=s[i]

&&k*v[i]

<=j;k++

)//與完全揹包相比僅僅是加了乙個判斷條件而已

f[i]

[j]=

max(f[i]

[j],f[i-1]

[j-v[i]

*k]+w[i]

*k);

樸素演算法的時間效率很低,通過下面的二進位制優化可以把遍歷每種物品的n[i]件物品的時間複雜度從o(n)優化為o(log n)

優化:通過展開化簡式子不可行,換用二進位制優化方式

第i種物品是有n[i]件的,這個n[i]可以被展開為n[i]=20+21+…+2k+c (其中2k+1

(20+21+…+2k可以表示區間[ 0,2k+1-1 ]的數,通過加上c這個數,能夠表示區間[0,n[i]]上的所有數)

同時記錄這些加數的值

那這樣的話對於[0,n[i]]的每乙個數,都可以用這些二進位制數表示。即為將n種物品轉化成cnt種物品【每種物品的可選擇數量都是2的某次方(某種物品的最後一種例外)】

完整**如下:

#include

#include

using

namespace std;

const

int n =

24010

, m =

2010

;//陣列開的元素個數n --> 2000*log2000 (log2000約等於11.幾)

int n, m;

int v[n]

, w[n]

;int f[m]

;int

main()

if(s >0)

//加上最後一位c

} n = cnt;

//將n種物品轉化成cnt種物品【每種物品的可選擇數量都是2的某次方(某種物品的最後一種例外)】

for(

int i =

1; i <= n; i ++

)//此處包含0 1揹包問題的優化,可詳見我的揹包專題

for(

int j = m; j >= v[i]

; j --

) f[j]

=max

(f[j]

, f[j - v[i]

]+ w[i]);

cout << f[m]

<< endl;

return0;

}

多重揹包二進位制優化

多重揹包二進位制優化 將價值數量相同的物品分成1,2,4,8.因為100以內任何數都可以由幾個2的n次方數組成。所以,有遍歷沒乙個數變為遍歷每乙個2的n次方數。例題 有n種物品,每種物品的數量為c1,c2.cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2.wn wi為整數 與之相...

多重揹包(二進位制優化)

馬上就要輕院校賽了,沒時間了,下面是網上找的多重揹包,感覺很好 void zeroonepack int cost,int weight,int n void completepack int cost,int weight,int n void multipack int c,int w,int ...

多重揹包二進位制優化

時間長不寫 感覺變菜了。整體優化思路和快速冪很相近 如果第i個物品有num i 個,花費是 c i 價值是 v i 那麼我們可以把它拆分成數個物品。比如某個物品數量是14 花費是cost 價值是value 1 2 4 7 就可以把14個相同物品看成 4 個不同的物品,物品 數量花費 價值第乙個 11...