0 1揹包再談

2022-04-01 07:47:58 字數 1196 閱讀 4407

搞了兩天的dp了,對01揹包又有了新的理解。網上有很多資料,可能都比我寫的好,只是記錄一下我的理解。

**編譯過不了,只是記錄揹包問題的思想。

參考:《演算法入門經典》

首先乙個引例:

物品無限的揹包問題——dag 硬幣問題

就是加了乙個權值的dag,ans = max(ans,dp(c-v[i])+w[i]);

由於01揹包問題,按照dag模型的話,不能表示每個物品是否拿過,這要求我們決策有序化。

決策的分層階段,d(i,j)當前階段是 i ,揹包容量是 j ,

邊界條件:

d(i,j) = 0; i>n;

答案 d(1,c);

狀態轉移方程:

d(i,j) = max(d(i+1,j),d(i+1,j-v[i])+w[i]);

還有一種就是對稱的定義:

前1~i個物品都放入時揹包容量為j 是的最優值。

f(i,j) = max(f(i-1,j),f(i-1,j-v[i])+w[i]);

答案是 f(n,c);

然後就是滾動陣列了:

這裡的dp順序很有講究。

f是從上到下,從右到左的遞推的。

計算f(i,j)時,f[j]儲存的是f(i-1,j)的值,f[j-v] 儲存的是 f(i-1,j-v)的值。

這樣狀態轉移方程就出來了:

f[j] = max(f[j],f[j-v]+w);

#include using

namespace

std;

#define num 2000

#define c 100000

intd[num][c];

int n; //

物品種量

///物品無限 —— dag 硬幣問題

intd[c];

bool

vis[c];

int dp(int

c) }

}int

main()

}///規劃方向

///對稱定義

///把1~i放到揹包裡面去

for(int i=1;i<=n;i++)

}///滾動陣列

memset(f,0,sizeof

(f));

for(int i=1;i<=n;i++) }}

return0;

}

揹包 01揹包

01揹包 有n種物品與承重為m的揹包。每種物品只有一件,每個物品都有對應的重量weight i 與價值value i 求解如何裝包使得價值最大。dp i,v 表示前i個物體 包括第i個 面對容量為v的揹包的最大價值,c i 代表物體i的重量,w i 代表物體i的價值 如果第i個物體不放入揹包,則揹包...

最大團問題 0 1揹包 再談分支限界

對於分支限界,其實思想和回溯很像,只是具體的實現方法不一樣。回溯用到遞迴,是深度優先搜尋 分支限界是用最大堆進行迴圈,是廣度優先搜尋。1.最大團問題 給出乙個無向連通圖,求出其最大完全子圖的節點數 分析 每乙個節點進行分析,如果可以放進去,則定為1,放入左節點,要是不能放進去,則定為0,放入右節點。...

揹包專題 01揹包

暑假集訓開始了,按照隊裡的分配,我是弄dp的,嘛,於是我又一次的開始了從01揹包開始學習,昨天將杭電的幾道01揹包重新做了一遍,下面講講我自己對於01揹包的理解。首先01揹包題目的雛形是 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。...