揹包問題的5種求解方法 記憶化搜尋或者動態規劃

2021-10-05 10:08:15 字數 1663 閱讀 3822

定義乙個方法rec(i,j)其中i表示第i個物品,j表示當前可以容許的重量

注意!我程式裡i都是0開始,也就是說第乙個物品的i為0

int

rec(

int i,

int j)

int res=0;

if(j)else

return res;

}

餘下的方法複雜度都達到了o(nw)級

先貼**,然後我做解釋吧!

//dp陣列首先都初始化為-1

intrec

(int i,

int j)

if(i==n)

int res=0;

//如果

if(j)else

//return時順便把這個答案儲存到dp陣列裡

return dp[i]

[j]=res;

}

這個**是不是和上面第乙個方法有點相似,無非是加了乙個dp動態陣列來儲存每一次求得結果。正式因為這個陣列,讓複雜度大大減小。

為什麼複雜度為o(nw)呢?n代表物品個數,w代表揹包最大容量,因為dp陣列在這道題裡只用了dp[0][0]到dp[n-1][w],所以複雜度就是o(nw)了!

動態規劃最最重要的就是要清楚陣列代表的什麼意思,不同的含義會有不同的迴圈方法,這也就是為什麼動態規劃方法多種多樣的原因了!

先貼**

int

solve()

else}}

return dp[0]

[w];

}

這裡dp陣列先初始化為0,要注意的是,這裡dp陣列中i=0不是代表第乙個物品了,而是從1開始

這個方法中陣列是什麼含義呢? dp[i][j]表示的是第i個物品挑選重量小於j時,可以實現總價值的最大值。 所以,狀態轉移如下

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

在不放當前物品和放置當前物品中求得最大值。

int

solve()

else}}

return dp[n]

[w];

}

dp陣列需要初始化為0

要注意的是,這裡dp陣列中i=0不是代表第乙個物品了,而是從1開始

此時dp[i][j]表示的含義是從0到i這i+1個物品所能實現總價值的最大值。所以狀態轉移如下

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

int

solve()

}return dp[w]

;}

一維陣列dp[j]的含義就是容量為j大小所能實現總價值的最大值。

int

solve()

}}return dp[n]

[w];

}

需要初始化陣列為0

這個方法主要體現的是狀態轉移的不同。從當前dp[i][j]出發,我們要更新dp[i+1][j]和dp[i+1][j+w[i]]的值。我們只需要考慮老值和新值哪個大去哪個即可。

揹包問題的求解

1 問題描述 假設有乙個能裝入總體積為t的揹包和n件體積分別為w1,w2,wn的物品,能否從n件物品中挑選若干件恰好裝滿揹包,即使w1 w2 wm t,要求找出所有滿足上述條件的解。2 設計功能要求 例如 當t 10,各件物品的體積時,可找到下列4組解 1,4,3,2 1,4,5 8,2 3,5,2...

記憶化搜尋解決揹包問題

為什麼要用二維陣列進行紀錄?記憶化最麻煩的還是記憶值的準確性 include include using namespace std struct noded 10000 long long n,m long long dp 1000 1000 一開始我直接使用的dp 1000000 以為將每個m對...

C語言遞迴方法求解揹包問題

十 揹包問題的求解 假設有乙個能裝入總體積為t的揹包和n件體積分別為w1 w2 wn 的物品,能否從n件物品中挑選若干件恰好裝滿揹包,即使w1 w2 wn t,要求找出所有滿足上述條件的解。例如 當t 10,各件物品的體積時,可找到下列4組解 1,4,3,2 1,4,5 8,2 3,5,2 incl...