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

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

生活随笔

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

编程问答

关于动态规划01背包问题的一些心得体会

發(fā)布時(shí)間:2024/1/1 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于动态规划01背包问题的一些心得体会 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

《算法筆記》動(dòng)態(tài)規(guī)劃之01背包問(wèn)題狀態(tài)轉(zhuǎn)移方程的代碼為:

for(int i = 1; i <= n; i++){ //n件物品for(int j = w[i]; j <= c; j++){ //每件物品的重量為w[i], 價(jià)值為v[i], 背包最大容量為cdp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i];} }

搜索CSDN大佬博客得出的代碼為:

for(int i = 1; i <= n; i++){for(int j = 1; j <= c; j++){if(j < w[i]){ //如果當(dāng)前背包容量不足以裝下第i件物品dp[i][j] = dp[i-1][j]; //只能選擇不裝}else{ //如果當(dāng)前背包容量足以裝下第i件物品//但由于裝第i件物品不一定使得價(jià)值最大,所以考慮裝與不裝第i件物品所能得到的最大價(jià)值dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]);}}}

個(gè)人更傾向于第二種代碼,對(duì)于第一種代碼的正確性存在疑問(wèn)。
原因是第一種代碼的內(nèi)層循環(huán),j從w[i]開(kāi)始取值,這樣在填表dp[i][j]的時(shí)候會(huì)漏填部分表格導(dǎo)致中間部分dp[i][j]的結(jié)果錯(cuò)誤。
舉個(gè)例子,假設(shè)現(xiàn)在有6件商品,背包容量最大為12
商品的重量為:w[i] = {4, 6, 2, 2, 5, 1}
商品的價(jià)值為:v[i] = {8, 10, 6, 3, 7, 2}
分別用兩種代碼填寫(xiě)dp數(shù)組,打印兩個(gè)表格。

#include <iostream> #include <cstring> #include <string> using namespace std; const int maxn = 100; int main(){int v[maxn], w[maxn], dp[maxn][maxn] = {0};int n, c;cin >> n >> c;for(int i = 1; i <= n; i++){ //輸入價(jià)值數(shù)組cin >> v[i];}for(int i = 1; i <= n; i++){ //輸入重量數(shù)組cin >> w[i];}for(int i = 1; i <=n; i++){ //第一種代碼for(int j = w[i]; j <= c; j++){dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]);}}for(int i = 1; i <= n; i++){ //打印dp數(shù)組for(int j = 1; j <= c; j++){cout << dp[i][j];if(j < c) cout << "\t";else cout << endl;}}return 0; } #include <iostream> #include <cstring> #include <string> using namespace std; const int maxn = 100; int main(){int v[maxn], w[maxn], dp[maxn][maxn] = {0};int n, c;cin >> n >> c;for(int i = 1; i <= n; i++){ //輸入價(jià)值數(shù)組cin >> v[i];}for(int i = 1; i <= n; i++){ //輸入重量數(shù)組cin >> w[i];}for(int i = 1; i <= n; i++){ //第二種代碼for(int j = 1; j <= c; j++){if(j < w[i]){dp[i][j] = dp[i-1][j];}else{dp[i][j] = max(dp[i-1][j], dp[i-1][j - w[i]] + v[i]);}}}for(int i = 1; i <= n; i++){ //打印dp數(shù)組for(int j = 1; j <= c; j++){cout << dp[i][j];if(j < c) cout << "\t";else cout << endl;}}return 0; }

兩種方法打印出來(lái)的數(shù)組分別如下:
第一種:

第二種:

可以看到,雖然兩種方法最優(yōu)解都是24,但中間部分dp[i][j]有了很大的出入。第二種的dp數(shù)組才是正確的。

總結(jié)

以上是生活随笔為你收集整理的关于动态规划01背包问题的一些心得体会的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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