日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法总结——背包问题与组和问题

發(fā)布時(shí)間:2025/3/20 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法总结——背包问题与组和问题 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

數(shù)據(jù)結(jié)構(gòu)與算法總結(jié)——背包問(wèn)題與組和問(wèn)題

  • 數(shù)據(jù)結(jié)構(gòu)與算法總結(jié)——背包問(wèn)題與組和問(wèn)題
  • 1. 背包問(wèn)題
  • 2.背包問(wèn)題的變形
  • 3. 組和問(wèn)題
  • 總結(jié)

數(shù)據(jù)結(jié)構(gòu)與算法總結(jié)——背包問(wèn)題與組和問(wèn)題

我覺(jué)得學(xué)習(xí)算法很重要的一點(diǎn)是舉一反三,題目是刷不完的(這個(gè)指的是我自己,我聽說(shuō)過(guò)有刷完一千多道leetcode的大佬…),背包問(wèn)題是我筆試面試過(guò)程中遇到非常多的一個(gè)類型,而且被坑了好幾次,因此我打算好好總結(jié)一下,而這個(gè)組和問(wèn)題(你沒(méi)有看錯(cuò),是組和,這個(gè)是我自己取的名字,英文題目叫Combination Sum)會(huì)和背包問(wèn)題由極大的相似之處,我在一次筆試的過(guò)程中將一組和問(wèn)題用背包問(wèn)題的解法去做而浪費(fèi)的不少時(shí)間,背包問(wèn)題應(yīng)該是可以求出答案的,但是不如組和問(wèn)題的專有解法來(lái)的干脆,因此我把這兩個(gè)問(wèn)題放在一起進(jìn)行一個(gè)總結(jié)。

1. 背包問(wèn)題

背包問(wèn)題建議看看《背包九講》,本文也主要是參考的《背包九講》中的內(nèi)容,我這里主要只總結(jié)一下比較基礎(chǔ)的三種——01背包、完全背包、多重背包,而混合背包和分組背包我目前還沒(méi)怎么接觸過(guò)(還是做題太少…),就先不做總結(jié)了。
(1)01背包

NNN 件物品和一個(gè)容量為 VVV 的背包。放入第 iii 件物品耗費(fèi)的費(fèi)用是 Ci1C_i^1Ci1?,得到的價(jià)值是 WiW_iWi?。求解將哪些物品裝入背包可使價(jià)值總和最大

狀態(tài)變量定義的是 F[i,v]F[i, v]F[i,v] 表示將前iii件物品恰放入一個(gè)容量為 vvv 的背包可以獲得的最大價(jià)值。則其狀態(tài)轉(zhuǎn)移方程便是:F[i,v]=max?{F[i?1,v],F[i?1,v?Ci]+Wi}F[i, v]=\max \left\{F[i-1, v], F\left[i-1, v-C_{i}\right]+W_{i}\right\} F[i,v]=max{F[i?1,v],F[i?1,v?Ci?]+Wi?}其偽代碼為:F[0,0..V]←0for?i←1to?Nfor?v←Cito?VF[i,v]←max?{F[i?1,v],F[i?1,v?Ci]+Wi}\begin{array}{l}{F[0,0 . . V] \leftarrow 0} \\ {\text { for } i \leftarrow 1 \text { to } N} \\ {\qquad \begin{aligned} \text { for } v & \leftarrow C_{i} \text { to } V \\ & F[i, v] \leftarrow \max \left\{F[i-1, v], F\left[i-1, v-C_{i}\right]+W_{i}\right\} \end{aligned}}\end{array} F[0,0..V]0?for?i1?to?N?for?v?Ci??to?VF[i,v]max{F[i?1,v],F[i?1,v?Ci?]+Wi?}??而對(duì)其進(jìn)行空間優(yōu)化之后偽代碼為:F[0..V]←0for?i←1to?Nfor?v←Vto?CiF[v]←max?{F[v],F[v?Ci]+Wi}\begin{array}{l}{F[0 . . V] \leftarrow 0} \\ {\text { for } i \leftarrow 1 \text { to } N} \\ {\qquad \begin{aligned} \text { for } v \leftarrow & V \text { to } C_{i} \\ & F[v] \leftarrow \max \left\{F[v], F\left[v-C_{i}\right]+W_{i}\right\} \end{aligned}}\end{array} F[0..V]0?for?i1?to?N?for?v?V?to?Ci?F[v]max{F[v],F[v?Ci?]+Wi?}??所謂空間優(yōu)化就是就是將原本的二維DP數(shù)組優(yōu)化為一維DP數(shù)組,能這樣做的理由是,從未優(yōu)化的偽代碼中可以看出,每次循環(huán)二維DP數(shù)組中更新的位置只和其正上方F[i?1,v]F[i-1, v]F[i?1,v]和左上方F[i?1,v?Ci]F\left[i-1, v-C_{i}\right]F[i?1,v?Ci?]有關(guān),因此可以用一維DP數(shù)組直接代替(這其實(shí)也叫做滾動(dòng)數(shù)組),那么空間優(yōu)化后的代碼如下:

int backPack(int V, vector<int> &C, vector<int> &W){int n = C.size();vector<int> F(V+1, 0);for(int i = 1; i<n; i++){for(int j = V; j>=C[i]; j--){F[j] = max(F[j],F[j-C[i]]+W[i]);}}return F[V]; }

(2)完全背包

NNN 種物品和一個(gè)容量為 VVV 的背包,每種物品都有無(wú)限件可用。放入第 iii 種物品的費(fèi)用是 CiC_iCi?,價(jià)值是 WiW_iWi?。求解:將哪些物品裝入背包,可使這些物品的耗費(fèi)的費(fèi)用總和不超過(guò)背包容量,且價(jià)值總和最大。

這里的狀態(tài)變量的定義和01背包是一樣的,但是狀態(tài)轉(zhuǎn)移方程稍有不同,如下:F[i,v]=max?{F[i?1,v?kCi]+kWi∣0≤kCi≤v}F[i, v]=\max \left\{F\left[i-1, v-k C_{i}\right]+k W_{i} | 0 \leq k C_{i} \leq v\right\} F[i,v]=max{F[i?1,v?kCi?]+kWi?0kCi?v}其偽代碼為F[0,0..V]←0for?i←1to?Nfor?v←Cito?Vfor?k←0to?j/CiF[i,v]←max?{F[i?1,v],F[i?1,v?kCi]+kWi}\begin{array}{l}{F[0,0 . . V] \leftarrow 0} \\ {\text { for } i \leftarrow 1 \text { to } N} \\ {\qquad \begin{aligned} \text { for } v &amp; \leftarrow C_{i} \text { to } V \\ &amp; \text{ for } k \leftarrow 0 \text{ to } j/C_i\\&amp;F[i, v] \leftarrow \max \left\{F[i-1, v], F\left[i-1, v-kC_{i}\right]+kW_{i}\right\} \end{aligned}}\end{array} F[0,0..V]0?for?i1?to?N?for?v?Ci??to?V?for?k0?to?j/Ci?F[i,v]max{F[i?1,v],F[i?1,v?kCi?]+kWi?}??完全背包由兩種優(yōu)化方法,第一種是利用二進(jìn)制的思想將其轉(zhuǎn)化為01背包,第二種是優(yōu)化為一維數(shù)組,其時(shí)間復(fù)雜度為O(VN)O(VN)O(VN)。用得更多的是第二種方法,因?yàn)樗_實(shí)很方便,第一種方法的思想主要用在多重背包問(wèn)題里,那么第二種方法優(yōu)化的偽代碼如下:F[0..V]←0for?i←1to?Nfor?v←Cito?VF[v]←max?(F[v],F[v?Ci]+Wi)\begin{array}{l}{F[0 . . V] \leftarrow 0} \\ {\text { for } i \leftarrow 1 \text { to } N} \\ {\qquad \begin{aligned} \text { for } v &amp; \leftarrow C_{i} \text { to } V \\ &amp; F[v] \leftarrow \max \left(F[v], F\left[v-C_{i}\right]+W_{i}\right) \end{aligned}}\end{array} F[0..V]0?for?i1?to?N?for?v?Ci??to?VF[v]max(F[v],F[v?Ci?]+Wi?)??這里可以看出來(lái),如果你對(duì)01背包熟悉的話,記住完全背包也就是一句話的事情,他們之間唯一不同的是第二個(gè)for循環(huán),完全背包是從CiC_iCi?VVV,01背包是從VVVCiC_iCi?,這個(gè)規(guī)則為什么會(huì)成立呢?《背包九講》中是這么說(shuō)的:

為什么這個(gè)算法就可行呢?首先想想為什么 01 背包中要按照 vvv 遞減的次序來(lái)循環(huán)。讓 vvv 遞減是為了保證第 iii 次循環(huán)中的狀態(tài) F[i;v]F[i; v]F[i;v] 是由狀態(tài) F[i?1;v?Ci]F[i ? 1; v ? C_i]F[i?1;v?Ci?]遞推而來(lái)。換句話說(shuō),這正是為了保證每件物品只選一次,保證在考慮“選入第 iii 件物品”這件策略時(shí),依據(jù)的是一個(gè)絕無(wú)已經(jīng)選入第 iii 件物品的子結(jié)果 F[i?1;v?Ci]F[i ? 1; v ? C_i]F[i?1;v?Ci?]。而現(xiàn)在完全背包的特點(diǎn)恰是每種物品可選無(wú)限件,所以在考慮“加選一件第 iii 種物品”這種策略時(shí),卻正需要一個(gè)可能已選入第 i 種物品的子結(jié)果 F[i;v?Ci]F[i; v ? C_i]F[i;v?Ci?],所以就可以并且必須采用 vvv 遞增的順序循環(huán)。這就是這個(gè)簡(jiǎn)單的程序?yàn)楹纬闪⒌牡览怼?/p>

這里給出按照第二種優(yōu)化后的代碼(其實(shí)真的就是把上面的代碼趴下來(lái)改一句話就行了)

int backPack(int V, vector<int> &C, vector<int> &W){int n = C.size();vector<int> F(V+1, 0);for(int i = 1; i<n; i++){for(int j = C[i]; j<=V; j--){F[j] = max(F[j],F[j-C[i]]+W[i]);}}return F[V]; }

(3)多重背包

NNN 種物品和一個(gè)容量為 VVV 的背包。第 iii 種物品最多有 MiM_iMi? 件可用,每件耗費(fèi)的空間是 CiC_iCi?,價(jià)值是 WiW_iWi?。求解將哪些物品裝入背包可使這些物品的耗費(fèi)的空間總和不超過(guò)背包容量,且價(jià)值總和最大。

同樣,多重背包的狀態(tài)變量定義和前兩者是相同的,不同的還是狀態(tài)轉(zhuǎn)移方程,如下:F[i,v]=max?{F[i?1,v?k?Ci]+k?Wi∣0≤k≤Mi}F[i, v]=\max \left\{F\left[i-1, v-k * C_{i}\right]+k * W_{i} | 0 \leq k \leq M_{i}\right\} F[i,v]=max{F[i?1,v?k?Ci?]+k?Wi?0kMi?}多重背包通常采用的優(yōu)化方式是通過(guò)二進(jìn)制思想轉(zhuǎn)化為01背包進(jìn)行求解,所謂二進(jìn)制思想按照我的個(gè)人理解就是,通過(guò)給數(shù)量為MiM_iMi?個(gè)的物體 iii 帶上二進(jìn)制標(biāo)簽 2k2^k2k 之后相當(dāng)于變成了多個(gè)數(shù)量為 1 的物體,然后通過(guò)對(duì)這些數(shù)量為 1 的物體采用取或者不取的方式最后組合成取具體數(shù)量的物體 iii 。這里直接給出一段多重背包的代碼,具體怎么進(jìn)行二進(jìn)制的可以通過(guò)代碼進(jìn)行理解

int main() {int n, w;cin>>n>>w;vector<int> weights;//物體重量vector<int> values;//物體價(jià)值vector<int> nums;//物體數(shù)量for(int i = 0; i<n; i++){int weight, value, num;cin>>weight>>value>>num;int temp = 1;while(num)//在輸入的時(shí)候進(jìn)行二進(jìn)制化{if(num>=temp){weights.push_back(temp * weight);values.push_back(temp * value);num -= temp;}else{weights.push_back(num * weight);values.push_back(num * weight);num = 0;}temp *= 2;}}//下面就是直接調(diào)用01背包的程序就可以了vector<int> dp(w+1, 0);for(int i = 0; i<weights.size(); i++){for(int j = w; j>=weights[i]; j--){dp[j] = max(dp[j], dp[j-weights[i]]+values[i]);}}cout<<dp[w]; }

上面的程序是在輸入的時(shí)候就直接根據(jù)物體的數(shù)量對(duì)物體的價(jià)值和重量進(jìn)行二進(jìn)制化,temp就是用來(lái)進(jìn)行二進(jìn)制化的變量,在循環(huán)中temp分別是1,2,22…2k?1,Mi?2k+11,2,2^{2} \ldots 2^{k-1}, M_{i}-2^{k}+11,2,222k?1,Mi??2k+1,通過(guò)將物體的價(jià)值和重量乘以這些系數(shù)實(shí)現(xiàn)二進(jìn)制化,二進(jìn)制化物體直接采用01背包的策略就可以直接求得多重背包最終的結(jié)果。

2.背包問(wèn)題的變形

好了,真正的重點(diǎn)來(lái)了,通過(guò)背包問(wèn)題的變形我們將引出來(lái)組和問(wèn)題,注意到,上面的背包問(wèn)題都是最典型形式,問(wèn)的都是給定一個(gè)背包容量VVV,怎么取放物體使得裝下的價(jià)值WWW最大 ,這類問(wèn)題的狀態(tài)變量的意義是價(jià)值,以01背包為例,其狀態(tài)轉(zhuǎn)移方程為F[i,v]=max?{F[i?1,v],F[i?1,v?Ci]+Wi}F[i, v]=\max \left\{F[i-1, v], F\left[i-1, v-C_{i}\right]+W_{i}\right\} F[i,v]=max{F[i?1,v],F[i?1,v?Ci?]+Wi?}那么背包問(wèn)題有一種很典型的變形形式是給定一個(gè)背包容量VVV,怎樣取放物體可以放滿背包,一共有幾種取放方式,對(duì)于這個(gè)問(wèn)題,我們就需要將狀態(tài)變量的意義定義為滿足方面背包條件的情況種類,以01背包為例,其狀態(tài)轉(zhuǎn)移方程就變?yōu)?#xff1a;F[i,v]=F[i?1,v]+F[i?1,v?Ci]F[i, v]= F[i-1, v]+ F\left[i-1, v-C_{i}\right] F[i,v]=F[i?1,v]+F[i?1,v?Ci?]對(duì)應(yīng)的代碼也給出來(lái)

int combinationSum(int V, vector<int> &C){int n = C.size();vector<int> F(V+1, 0);V[0] = 1;for(int i = 1; i<n; i++){for(int j = V; j>=C[i]; j--){F[j] = F[j]+F[j-C[i]];}}return F[V]; }

注意這里,除了狀態(tài)轉(zhuǎn)移方程有點(diǎn)不太一樣之外,還有就是初始話的時(shí)候需要將V[0]初始話為1,這里注意一下就好了,這類問(wèn)題又稱找零錢問(wèn)題,leetcode中還有一個(gè)找零錢問(wèn)題的變形(332題),如下:

給定不同面額的硬幣 coins 和一個(gè)總金額 amount。編寫一個(gè)函數(shù)來(lái)計(jì)算可以湊成總金額所需的最少的硬幣個(gè)數(shù)。如果沒(méi)有任何一種硬幣組合能組成總金額,返回 -1。

這個(gè)題目看上去像是完全背包問(wèn)題,但是題目所求的既不是最大價(jià)值,也不是方案數(shù),而是最少的硬幣個(gè)數(shù),這個(gè)怎么做呢?方法也是使用動(dòng)態(tài)規(guī)劃,但是狀態(tài)轉(zhuǎn)移方程的思路和上述討論的方式不太相同,具體如下,我們維護(hù)一個(gè)一維動(dòng)態(tài)數(shù)組 dp,其中 dp[i] 表示錢數(shù)為i時(shí)的最小硬幣數(shù)的找零,注意由于數(shù)組是從0開始的,所以要多申請(qǐng)一位,數(shù)組大小為 amount+1,這樣最終結(jié)果就可以保存在 dp[amount] 中了。初始化 dp[0] = 0,因?yàn)槟繕?biāo)值若為0時(shí),就不需要硬幣了。其他值可以初始化是 amount+1,為啥呢?因?yàn)樽钚〉挠矌攀?,所以 amount 最多需要 amount 個(gè)硬幣,amount+1 也就相當(dāng)于當(dāng)前的最大值了,注意這里不能用整型最大值來(lái)初始化,因?yàn)樵诤竺娴臓顟B(tài)轉(zhuǎn)移方程有加1的操作,有可能會(huì)溢出,除非你先減個(gè)1,這樣還不如直接用 amount+1 舒服呢。好,接下來(lái)就是要找狀態(tài)轉(zhuǎn)移方程了,沒(méi)思路?不要緊!回歸例子1,假設(shè)我取了一個(gè)值為5的硬幣,那么由于目標(biāo)值是 11,所以是不是假如我們知道 dp[6],那么就知道了組成 11 的 dp 值了?所以更新 dp[i] 的方法就是遍歷每個(gè)硬幣,如果遍歷到的硬幣值小于i值(比如不能用值為5的硬幣去更新 dp[3])時(shí),用 dp[i - coins[j]] + 1 來(lái)更新 dp[i],所以狀態(tài)轉(zhuǎn)移方程為(分析來(lái)源[LeetCode] 322. Coin Change 硬幣找零):dp[i]=min(dp[i],dp[i?coins[j]]+1)dp[i] = min(dp[i], dp[i - coins[j]] + 1) dp[i]=min(dp[i],dp[i?coins[j]]+1)代碼如下:

int coinChange(vector<int>& coins, int amount) {if(coins.empty())return 0;vector<int> dp(amount+1,amount+1);dp[0] = 0;for(int i = 1; i<=amount; i++){for(int j = 0; j<coins.size(); j++){if(coins[j]<=i){dp[i] = min(dp[i], dp[i-coins[j]]+1);}}}return dp[amount] == amount+1 ? -1 : dp[amount]; }

這里需要讀者細(xì)細(xì)去理解這幾種變形中的不同,然后我們繼續(xù)變形,現(xiàn)在僅僅是要求輸出有多少種情況,如果題目要求將所有的情況都打印出來(lái)呢?用背包能做嗎?答案是可以的,但是比較麻煩,一種更加簡(jiǎn)單的思路是采用回溯加剪枝,也就是圖論的方式去解決,也就是接下來(lái)要討論的組和問(wèn)題

3. 組和問(wèn)題

組和問(wèn)題在leetcode中一共由四道,是一個(gè)系列,分別是
39. 組合總和
40. 組合總和 II
216. 組合總和 III
377. 組合總和 Ⅳ
其實(shí)這個(gè)系列并不難,簡(jiǎn)單分析下:
(1)組和問(wèn)題

給定一個(gè)無(wú)重復(fù)元素的數(shù)組 candidates 和一個(gè)目標(biāo)數(shù) target ,找出 candidates 中所有可以使數(shù)字和為 target 的組合。 candidates 中的數(shù)字可以無(wú)限制重復(fù)被選取。

這個(gè)其實(shí)就是相當(dāng)于背包問(wèn)題中的完全背包問(wèn)題,完成組和問(wèn)題需要實(shí)現(xiàn)一個(gè)深度搜索的函數(shù),具體代碼如下:

void dfs(vector<int>& candidates, int target, int start, vector<int>& out, vector<vector<int>>& res) {if(target<0)return;if(target == 0){res.push_back(out);return;}for(int i = start; i<candidates.size(); i++){out.push_back(candidates[i]);dfs(candidates, target-candidates[i], i, out, res);out.pop_back();} }vector<vector<int>> combinationSum(vector<int>& candidates, int target) {vector<vector<int>> res;vector<int> out;dfs(candidates, target, 0, out, res); return res; }

(2)組和問(wèn)題II

給定一個(gè)數(shù)組 candidates 和一個(gè)目標(biāo)數(shù) target ,找出 candidates 中所有可以使數(shù)字和為 target 的組合。candidates 中的每個(gè)數(shù)字在每個(gè)組合中只能使用一次。

這個(gè)相當(dāng)于是01背包問(wèn)題,和上面稍有不同的處理方式是,這里因?yàn)槊總€(gè)數(shù)字只能使用一次,因此需要先對(duì)數(shù)組進(jìn)行一次排序,然后遞歸取數(shù)的時(shí)候控制不要重復(fù)取就好了,代碼如下:

void dfs(vector<int>& candidates, int target, int start, vector<int>& out, vector<vector<int>>& res) {if(target<0)return;if(target == 0){res.push_back(out);return;}for(int i = start; i<candidates.size(); i++){if(i>start && candidates[i] == candidates[i-1]) continue;//判斷相鄰兩個(gè)數(shù)據(jù)是否相同,避免重復(fù)out.push_back(candidates[i]);dfs(candidates, target-candidates[i], i+1, out, res);//將i改成i+1,避免重復(fù)out.pop_back();} }vector<vector<int>> combinationSum(vector<int>& candidates, int target) {vector<vector<int>> res;vector<int> out;sort(candidates.begin(), candidates.end());dfs(candidates, target, 0, out, res);return res; }

(3)組和問(wèn)題III

找出所有相加之和為 n 的 k 個(gè)數(shù)的組合。組合中只允許含有 1 - 9 的正整數(shù),并且每種組合中不存在重復(fù)的數(shù)字。

還是很類似的,這里只是規(guī)定了取的個(gè)數(shù),有點(diǎn)類似與多重背包,但不完全是,代碼如下:

void dfs(int k, int n, int start, vector<int>& out, vector<vector<int>>& res) {if(n<0)return;if(n == 0 && out.size() == k)//這里限制了取的數(shù)量{res.push_back(out);return;}for(int i = start; i<=9; i++){out.push_back(i);dfs(k, n-i, i+1, out, res);//i+1保證了不會(huì)重復(fù)取out.pop_back();} }vector<vector<int>> combinationSum3(int k, int n) {vector<vector<int>> res;vector<int> out;dfs(k, n, 1, out, res);return res; }

(4)組和問(wèn)題IV

給定一個(gè)由正整數(shù)組成且不存在重復(fù)數(shù)字的數(shù)組,找出和為給定目標(biāo)正整數(shù)的組合的個(gè)數(shù)。

這是何方神圣?這不就是01背包嗎!是的,但是leetcode上這道題和01背包有些不同的是,組合的順序不同屬于不同的組合,因此其和01背包的解題思路會(huì)稍有差別,先看代碼

int combinationSum4(vector<int>& nums, int target) {int n = nums.size();vector<int> dp(target+1);dp[0] = 1;for(int i = 1; i<=target; i++){for(int j = 0; j<n; j++){if(i>=nums[j])dp[i] = dp[i] + dp[i-nums[j]];}}return dp[target]; }

觀察發(fā)現(xiàn)和01背包不同的是,如果要求組合的順序不同屬于不同的組合,就內(nèi)外循環(huán)的順序換一下就好了,這個(gè)解法的思路和爬梯子的思路就更加相似的,比如說(shuō)對(duì)于 [1,2,3] 4,這個(gè)例子,當(dāng)我們?cè)谟?jì)算 dp[3] 的時(shí)候,3可以拆分為 1+x,而x即為 dp[2],3也可以拆分為 2+x,此時(shí)x為 dp[1],3同樣可以拆為 3+x,此時(shí)x為 dp[0],我們把所有的情況加起來(lái)就是組成3的所有情況了。

總結(jié)

通過(guò)上面的分析可以看出來(lái),如果是求方案數(shù)的話通常是用動(dòng)態(tài)規(guī)劃的方法,如果是要求輸出方案的話通常是用回溯加剪枝的方法,從本質(zhì)上說(shuō),這兩者是等價(jià)的,最終都是搜索了一顆隱式樹,回溯加剪枝是深度優(yōu)先搜索的過(guò)程,而動(dòng)態(tài)規(guī)劃更像是層序遍歷的過(guò)程,真正體會(huì)這兩者之間的關(guān)系我還需要刷更多的題。

總結(jié)

以上是生活随笔為你收集整理的数据结构与算法总结——背包问题与组和问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。