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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

动态规划 —— 01背包问题

發布時間:2024/5/6 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划 —— 01背包问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

01背包問題

有n個重量和價值分別為wi,vi的物品。
從這些物品中挑選出總重量不超過W的物品,
求所有挑選方案中價值總和的最大值。

針對每個物品是否放入背包進行搜索

#include <iostream>#define MAX_N 100using namespace std;int n, W; int w[MAX_N], v[MAX_N];int rec(int i, int j) { //從第i個物品開始挑選總重量小于j的部分int res;if (i == n) res = 0; //已經沒有剩余物品了else if (j < w[i]) res = rec(i + 1, j); //無法挑選這個物品else res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]); //挑選和不挑選的兩種情況都嘗試一下return res; }int main() {cin >> n;for (int i = 0; i < n; i++)cin >> w[i] >> v[i];cin >> W;cout << rec(0, W) << endl;return 0;

這種方法的搜索深度是n,而且每一層的搜索都需要兩次分支,最壞就需要O(2n)的時間,當n比較大的時候就沒辦法解了。

為了避免產生重復計算采用記憶化搜索

#include <iostream> #include <cstring>#define MAX_N 100 #define MAX_W 100using namespace std;int n, W; int w[MAX_N], v[MAX_N]; int dp[MAX_N + 1][MAX_W + 1];int rec(int i, int j) {if (dp[i][j]) return dp[i][j]; //已經計算過的話直接使用之前的結果int res;if (i == n) res = 0;else if (j < w[i]) res = rec(i + 1, j);else res = max(rec(i + 1, j), rec(i + 1, j - w[i]) + v[i]);return dp[i][j] = res; }int main() {cin >> n;for (int i = 0; i < n; i++)cin >> w[i] >> v[i];cin >> W;memset(dp, 0, sizeof(dp));cout << rec(0, W);return 0; }

對于同樣的參數,只會在被調用到時執行遞歸部分,第二次之后都會直接返回。參數的組合不過nW種,而函數內只調用2次遞歸,所以只需要O(nW)的復雜度就能解決。

DP數組

記dp[i][j]根據rec的定義,從第i個物品開始挑選總重小于j時總價值的最大值。

遞推公式:
dp[n][j]=0
if(j<w[i]) dp[i][j]=dp[i+1][j]
else dp[i][j]=max(rec(i+1,j),rec(i+1,j-w[i])+v[i])

#include <iostream>#define MAX_N 100 #define MAX_W 100using namespace std;int n, W; int w[MAX_N], v[MAX_N]; int dp[MAX_N + 1][MAX_W + 1];int main() {cin >> n;for (int i = 0; i < n; i++)cin >> w[i] >> v[i];cin >> W;for (int i = n - 1; i > -1; i--) {for (int j = 0; j < W + 1; 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]);}}cout << dp[0][W];return 0; }

總結

以上是生活随笔為你收集整理的动态规划 —— 01背包问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。