1. 程式人生 > >01揹包 ,完全揹包,多重揹包 dp (動態規劃入門dp)

01揹包 ,完全揹包,多重揹包 dp (動態規劃入門dp)

dp 動態規劃,確實難啃, 光 最簡單的 揹包問題,就 費老大勁.

思想! 思想! 思想!   類似於遞推, 區域性找 關係. 

揹包問題,  就兩種狀態  放還是不放?   其實關於揹包放不放的問題,如果用二進位制思想來表示的話

很好理解,  0 代表不放 1 代表放;   那麼對於現有的情況  假設有 n個物品 則 2進位制則對應的長度應該為n 對於每一個物品用0 1 表示 000xx~~~111xx 數的大小几位pow(2,n);

for(i=0;i<pow(2,n);i++)
{
	temp=i;
	for(j=0;j<n;j++)
	{
		if(temp%2)//放 
			執行語句
		temp/=2;
	}

01揹包 可以直接用二進位制來表示,但是 當資料量 過大時 就會超時, 比較這是暴力.

01揹包 的思想就是  對於這個物品,我要比較 我放進去的 價值大還是不放的價值大
轉換成方程  f[i][v] = Max{f[i−1][v] ,f[i−1][v−wei[i]] + val[i]};前面就是 不放,後面 是放, 放進去後,揹包的容量減少後的 + 放進去的價值=此時放進去的總價值,  二者比較!
轉換成一維方程  逆序   逆序的目的是 保證後一個f[v]和f[v-we[i]]+val[i]是前一狀態的
for(i=0;i<n;i++)
	for(j=c;j>=we[i];j--) //逆序!
	{
		dp[j]=max(dp[j],dp[j-we[i]]+val[i]);
	}

01 揹包題目
HDU2546:飯卡
http://acm.hdu.edu.cn/showproblem.php?pid=2546
 
HDU1171:BigEvent in HDU
http://acm.hdu.edu.cn/showproblem.php?pid=1171
 
HDU2602:BoneCollector (模板題)
http://acm.hdu.edu.cn/showproblem.php?pid=2602
 
HDU2639:BoneCollector II(01揹包第k優解)
http://acm.hdu.edu.cn/showproblem.php?pid=2639
 
HDU2955:Robberies
http://acm.hdu.edu.cn/showproblem.php?pid=2955
 
HDU3466:ProudMerchants
http://acm.hdu.edu.cn/showproblem.php?pid=3466
 
HDU1864:最大報銷額
http://acm.hdu.edu.cn/showproblem.php?pid=1864

完全揹包問題,  在01揹包上,   將物品個數 改為無限個,此時二進位制 思想 對於使用個數 就不好用了,  因為你可以用無數個,
此時 對於無限制時, 雖然可以在01 的基礎上優化,將 價值小並且重量還大的 給優化掉, 這樣的肯定不會選擇.
但 極端問題,就難以解決.
同樣 完全揹包的轉化 
f[i][v]=Max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v}k的取值不同 f[][]的權值也發生改變   k可以去1,2,3,4,5,6 無數個

for i=1->>n;
    for j=0-->>V// 這裡 變成正序  
        f[v]=max{f[v],f[v-c[i]]+w[i]}

正序 就保證了 我們對於每一個都有若干個可能來使用
/*,這正是為了保證每件物品只選一次,保證在 考慮“選入第i件物品”這件策略時,依據的是一個絕無已經選入第i件物品的子結果f[i-1][v-c[i]]。 而現在完全揹包的特點恰是每種物品可選無限件,所以在考慮“加選一件第i種物品”這種策略 時,卻正需要一個可能已選入第i種物品的子結果f[i][v-c[i]],所以就可以並且必須採用v=0..V的順 序迴圈。這就是這個簡單的程式為何成立的道理。 */  --> 大牛的 <揹包九講>
完全揹包題目:
Hdu 1114:
http://acm.hdu.edu.cn/showproblem.php?pid=1114 
Hdu 1248:
http://acm.hdu.edu.cn/showproblem.php?pid=1248
Hdu2159:
http://acm.hdu.edu.cn/showproblem.php?pid=2159

多重揹包: 類似於母函式,  母函式 其實更好理解;
有N種物品和一個容量為V的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值 是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大
母函式的思想也是如此 給你 價值, 物品數量的限制, 然後湊,
f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}<<--限制條件.


把每n[i] 中的每個物品都當成一個獨立的物品,而這 n[i] 個物品能夠表示的重量其實用 log n[i]個組合後的物品就能表示。


多重揹包
Hdu2191:
http://acm.hdu.edu.cn/showproblem.php?pid=2191
Hdu 2844:
http://acm.hdu.edu.cn/showproblem.php?pid=2844
Poj 1014
http://poj.org/problem?id=1014