完全揹包 經典DP問題 基本法 滾動陣列法

2021-08-20 01:27:42 字數 1067 閱讀 1314

完全揹包問題,在已知物品個數( i )和最大容量( j )後,從i個物品中選取最大價值總和。(每個物品可以選取無數次)

與01揹包問題所不同的就在這個每個物品可以選取多次上了,原有的狀態轉移方程加上選取當前物品的個數變數( knd ),即在滿足k[ind]<=jnd時,狀態轉移方程為dp[ind][jnd]=max(dp[ind-1][jnd-knd*k]+knd*value,dp[ind-1][jnd]),0<=knd*k<=jnd。與01揹包問題相同,k[ind]>ind時,dp[ind][jnd]=dp[ind-1][jnd]。

稍稍改動01揹包基本法即可。

#include#define max(a,b) (a>b?a:b)

int dp[1005][10005];

int k[1005], value[1005];

int main(int argc, char* argv)

} }printf("%d\n", dp[i][j]);

return 0;

}

在遞增knd求取最大值的時候,必須要另建乙個變數,否則可能出現都比dp[ind-1][jnd]大,導致dp[ind][jnd]最終值是knd最大時的價值而非價值最大的情況!

滾動陣列法改起來就更簡單了,01揹包問題時必須從後往前滾動,從而保證每次都是歷史資料。完全揹包問題只需反過來,從前往後滾動即可,這樣每次滾動用到的dp[ind-k]就都是最新的資料了,也就是從可以取當前物品更新最大值的最低容量開始更新最大值,雖然每次只能在原有基礎上加上乙個當前物品,但是小容量的揹包已經根據當前物品更新過了最大值,所以較大容量的揹包如果滿足更新最大值條件,也就是對應的容量加上了最合適數目的當前物品。

#include#include#include#define max(a,b) (a>b?a:b)

int dp[10005];

int main(int argc, char* argv)

printf("%d\n", dp[j]);

return 0;

}

滾動陣列法比基本法寫起來省力,複雜度也低,是基礎揹包問題首選方法。

DP之完全揹包問題

such as 設有n種物品,每種物品有乙個重量及乙個價值。但每種物品的數量是無限的,同時有乙個揹包,最大載重量為m,今從n種物品中選取若干件 同一種物品可以多次選取 使其重量的和小於等於m,而價值的和為最大。對於這個問題,啊,還是直接上 吧,在 中理解,解一 只需在01揹包上稍稍改善以下就行 in...

完全揹包問題講解(dp)

此題之前先分析兩種常見的揹包問題,01揹包與完全揹包 01揹包 在m件物品中取出若干件物品放到揹包中,每件物品對應的體積v1,v2,v3,對應的價值為w1,w2,w3,每件物品之多拿一件。解決方案 考慮用動態規劃的方法來解決,這裡的 階段是 在前n件物品中,選取若干件物品放入揹包中 狀態是 在前n件...

經典揹包問題 01揹包 完全揹包 多重揹包

1 for int i 0 i 2for int j w j size i j 3 f j max f j f j size i value i 1 for int i 0 i 2for int j size i j w j 3 f j max f j f j size i value i f w ...