完全揹包問題是指
有n種物品和乙個容量為v的揹包,每一種物品都是有無限的個數。也就是從每種物品角度分析,與其相關的策略不是選不選的問題了 已經轉換為選多少個的問題了
其實說到這裡你難道不覺得有點像dag圖的銀幣問題嗎 只是那裡的權值是1 這裡的權值是w
(其實我一開始在想乙個問題 dag圖不是確定起點以及終點的求最小或者最長路徑的嘛 這裡只是確定了起點 而且終點只是乙個範圍值 因為有可能是放不滿的)
但是再想想dag圖的硬幣問題也是放不滿的,因為你不能保證每一都能剛剛好籌到n 所以這裡完全揹包問題和dag圖的硬幣問題是一樣的,所以當你求最大值的時候就要初始化陣列為負無窮但是陣列0的地方為0
這樣就可以保證上乙個是存在的
那麼按照dag圖的硬幣問題 就是可以處理每乙個狀態 (每乙個狀態都是選擇每乙個揹包來計算 然後把個數轉換為重量)
for(int i=1;i<=s;i++)
for(int j=1;j<=n;j++)
if(i>=v[j])
時間複雜都是ns
現在我來說說完全揹包問題沒有優化的思路吧,其實完全揹包問題也是有點像01揹包問題那樣,但是因為揹包的數目是無限的 那麼轉移方程是f[i][v]=max 每一狀態都要處理o(v/c[i])次 那麼總的處理次數是超過o(vn)
這裡有乙個小小的思路吧 假如有兩個揹包 揹包體積第乙個比第二個小 並且第乙個揹包的價值比第二個大 那麼就要捨棄第二個了 但是這樣還是改變不了最不利的情況
現在說一下揹包問題的二進位制優化問題
其實01揹包問題是最簡單的揹包問題 那麼我們就在想能不能把完全揹包問題以及多重揹包問題轉換為01揹包問題,其實這裡之間的轉換就是差了個二進位制優化的操作,就是把乙個揹包為乙個每次能選擇一次的新揹包集合
下面先說說關於多重揹包的二進位制優化(個人覺得這個比較容易理解)
假設有一種大公尺只有m袋 例如m為100 利用二進位制來分解
for(int j=1;j<=a[i].num;j<<=1)
當a[i].num不為0的時候就
weigh[coun]=a[i].num*a[i].weight;
size[coun++]=a[i].num*a[i].value;
100=1+2+4+8+16+32+37
本來正常的思路是把100弄成100個1 即100個只能使用一次的物品 但是現在把100弄成1+2+4+8+16+32+37 7個數可以組合成100以內的任意乙個數 所以可以這樣拆分 把每乙個揹包都拆成乙個集合之後 在進行01揹包的處理
for(int i=0;i0)
}//--------------------0 1 揹包問題求解--------------------------------//
memset(dp,0,sizeof(dp));
for(int i=0;i=size[i];j--)
dp[j]=max(dp[j],dp[j-size[i]]+weigh[i]);
好了現在來說一下完全揹包問題的二進位制優化問題吧 因為完全揹包問題每一種揹包都是沒有數目的要求的。
所以你只需要你所弄的揹包集合的空間集合是小於總集合的
當跳出第一迴圈的時候 應該補齊剩下的(剩下的空間除以自己空間剩餘的個數)
其實還是有一種更加方便的思路的 就是用乙個陣列記錄每一種揹包最多可以存在的數目 然後就可以把它視為
限制的個數 然後就可以像多重揹包那樣處理
揹包問題 (二進位制優化模版)
51 nod 有n種物品,每種物品的數量為c1,c2 cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的種類,w為揹包的容量。...
多重揹包問題的二進位制優化
前情提要 動態規劃 揹包問題 多重揹包問題 多重揹包問題 有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 這題目和完全揹包問題很類似,特點是 每種物品都有自己特異的件數 花費 價值。樸素演算法 每種物品有n i 件可以取用,需要列舉每種物品選了多少件 ...
多重揹包二進位制優化
多重揹包二進位制優化 將價值數量相同的物品分成1,2,4,8.因為100以內任何數都可以由幾個2的n次方數組成。所以,有遍歷沒乙個數變為遍歷每乙個2的n次方數。例題 有n種物品,每種物品的數量為c1,c2.cn。從中任選若干件放在容量為w的揹包裡,每種物品的體積為w1,w2.wn wi為整數 與之相...