經典款動態規劃題,偶爾遇見了所以寫一下,這個基礎上的提高版可以看一下我的這篇部落格小a點菜
題目描述
有n件物品,每件物品的重量為t[i],價值為val[i]。現有乙個容量為v的揹包,問如何選取物品放入揹包,使得揹包內物品的總價值最大。其中
每種物品都只有一件。
令dp[i][j]來表示前i件物品裝入容量為j的揹包所能得到的最大總價值。
題解
分解成子問題,縮小原問題,然後運用動態轉移方程
dp[i][j]=max(dp[i-1][j],dp[i-1][j-t[i]]+val[i]
即每個物品選或不選裡取最大值
int n,v,t[10],val[10],dp[10][10];// 這裡就不需要設邊界為0 巨集定義陣列裡均為0
int main()
else
dp[i][j]=dp[i-1][j]; //放不下則數量不變
} }cout然後可以進行簡化dp成一維陣列
細心的一定發現剛才用的dp陣列得空間是乙個n*v的,如果n和v都比較大的情況下,有的題目的記憶體空間不給你很多,如果繼續開闢這麼大的陣列會報記憶體超限的錯誤
下面將會說到怎麼把n×v的dp 陣列壓縮成w大小的空間:
我們可以看到,要想得到 dp[i][j],我們需要知道 dp[i - 1][j] 和 dp[i - 1][j - t[i]],由於我們使用二維陣列儲存中間狀態,所以可以直接取出這兩個狀態。
大家有沒有發現第 i 個物品的是由第 i - 1個物品推出來的,也就是剛才讓大家比對的那個**,你要仔細的走了一遍那個**,一定會發現,第i行的填充是由第i - 1行推出來的,如果建立乙個陣列dp[ j ] 那麼如果當 i = 2,dp[j]陣列儲存的是當i=1時候&&揹包還可承受重量為v時候的價值,那麼咱們就可以直接利用dp[j],作為i - 1時候的價值,但要注意一點,在遍歷重量的之後,為了保證當改變dp[j]時,不會影響後面對dp[j]的計算,咱們列舉重量的時候是從大到小列舉的。所以遞推方程改為:
1、dp[j] = dp[j] // 不加入第i個物品
2、dp[j] = dp[j - t[i]] + val[i] // 加第i個物品
所以:dp[j] = max( dp[j] , dp[j - t[i]] + val[i] )
#includeusing namespace std;
int n,v,t[10],val[10],dp[10];// 這裡就不需要設邊界為0 巨集定義陣列裡均為0
int main()
} cout<
}
動態規劃之0 1揹包詳解
動態規劃是用空間換時間的一種方法的抽象。其關鍵是發現子問題和記錄其結果。然後利用這些結果減輕運算量。比如01揹包問題。乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,它們的重量分別是w1,w2,wn,它們的價值分別為p1,p2,pn.若每種物品只有一件求旅行者能獲得最大總價值。輸入格式 m,n...
動態規劃之0 1揹包詳解
動態規劃是用空間換時間的一種方法的抽象。其關鍵是發現子問題和記錄其結果。然後利用這些結果減輕運算量。比如01揹包問題。乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,它們的重量分別是w1,w2,wn,它們的價值分別為p1,p2,pn.若每種物品只有一件求旅行者能獲得最大總價值。輸入格式 m,n...
01揹包問題詳解 動態規劃
題目 給定n個專案的權重和價值 利潤 將這些專案放入最大容量w的揹包中,以獲得揹包中的最大總值 利潤 此時我們由這個問題得到了乙個子問題通用的解決方案,來檢查我得到的利潤 通過挑選專案或不挑選該專案這也就是選與不選的問題 當我選擇物品時,我需要將其從計算中移除,因為您已經對當前物品進行了處理,並通過...