二維費用揹包問題 空間優化(滾動陣列)

2021-08-07 15:41:03 字數 2186 閱讀 7915

題目描述:

在計算機世界,我們一直追求用最小的資源產生最大的價值。

現在,假設你可以支配m個0和n個1。同時有一些只有0和1組成的字串。

你的任務是用這些0和1去組成這些字串,輸出最多能組成多少個字串。每個0和1只能被使用一次。

樣例輸入

樣例一

輸入: array = , m = 5, n = 3

輸出: 4

解釋: 用5個0和3個1可以至多組成4個給定字串,分別為「10」、」0001」、」1」、」0」。

該題意可以轉換為==》你有容量為m個0,n個1的揹包,然後給你如何把字串陣列中的字串放到該揹包中,使得放的字串數目盡可能地多?

然後就可以得出去狀態轉移方程:

dp[i][j][k]代表有j個0和k個1的揹包,然後把前i個串放進去該揹包中,所放的字串數目的最大值

dp[i][j][k] = max

**如下:

#include #include #include using namespace std;

#define maxn 128

string s = ;

int m = 5;//0的數目

int n = 3;//1的數目

int zeronum[maxn], onenum[maxn];

int dp[maxn][maxn][maxn];

int main()

else

} }for (int i = 1; i <= 5; i++)

else

}} }

cout << dp[5][m][n] << endl;

return 0;

}

空間優化(滾動陣列):

由於前i個串的情況都是由前i-1個串推導出來的,與前1~i-2的情況沒有任何的關係,這也就是無後效性(個人理解,不對求糾正),然後我們可以把這一維去掉,即狀態轉移方程變成:

dp[i][j][k] = max =》dp[j][k] = max(j、k的遍歷順序要變成倒序)

變成倒序的理由:因為dp[i][j][k]是由dp[i-1][j - zeronum[i]][k - onenum[i]]推導出來的,而不是dp[i][j - zeronum[i]][k - onenum[i]]

所以dp[i][j - zeronum[i]][k - onenum[i]]必須後於dp[i][j][k]求值才能保證dp[i][j][k]是由dp[i-1][j - zeronum[i]][k - onenum[i]]推導而來的

**如下:

#include #include #include using namespace std;

#define maxn 128

string s = ;

int m = 5;//0的數目

int n = 3;//1的數目

int zeronum[maxn], onenum[maxn];

int dp[maxn][maxn];

int main()

else

} }for (int i = 1; i <= 5; i++)

}} }

cout << dp[m][n] << endl;

return 0;

}

二維費用的揹包問題

問題 二維費用的揹包問題是指 對於每件物品,具有兩種不同的費用 選擇這件物品必須同時付出這兩種代價 對於每種代價都有乙個可付出的最大值 揹包容量 問怎樣選擇物品可以得到最大的價值。設這兩種代價分別為代價1和代價2,第i件物品所需的兩種代價分別為a i 和b i 兩種代價可付出的最大值 兩種揹包容量 ...

二維費用的揹包問題

題目 toj3596 題意 有n張光碟,每張光碟有乙個價錢,現在要從n張光碟中買m張,預算為l,每張光碟有乙個快樂值,要求在不超過預算並且恰好買m張,使得快樂值最大。解答 典型的二維費用揹包問題,另外一種隱含的費用為個數,每個物品的個數費用為1。要求恰好買m張表示要求恰好裝滿,所以初始化不是0,而是...

二維費用的揹包問題

有 n nn 件物品和乙個容量是 v vv 的揹包,揹包能承受的最大重量是 mmm。每件物品只能用一次。體積是 v iv i vi 重量是 m im i mi 價值是 w iw i wi 求解將哪些物品裝入揹包,可使物品總體積不超過揹包容量,總重量不超過揹包可承受的最大重量,且價值總和最大。輸出最大...