01揹包問題

首先01揹包題目的雛形是ios

N件物品和一個容量爲V的揹包。第i件物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使價值總和最大。編程

01揹包的特色就是:每種物品僅有一件,能夠選擇放或不放。數組

其狀態轉移方程是:url

f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}spa

對於這方方程其實並不難理解,方程之中,如今須要放置的是第i件物品,這件物品的體積是c[i],價值是w[i],所以f[i-1][v]表明的就是不將這件物品放入揹包,而f[i-1][v-c[i]]+w[i]則是表明將第i件放入揹包以後的總價值,比較二者的價值,得出最大的價值存入如今的揹包之中。code

理解了這個方程後,將方程代入實際題目的應用之中,可得blog

1 for(i = 1; i<=n; i++)
2 {
3     for(j = v; j>=c[i]; j--)//在這裏,揹包放入物品後,容量不斷的減小,直到再也放不進了
4     {
5         f[i][v]=max(f[i-1][v],f[i-1][j-c[i]]+w[i]);
6     }
7 }

也能夠經過一維數組複用,來就行空間壓縮:ip

1     for(int i=0;i<n;i++)
2     {
3         for(int j=m;j>=h[i];j--)
4         {
5             dp[j]=max(dp[j],dp[j-h[i]]+v[i]);
6         }
7     }

 

 

 

來一發牛客上的一個雙重揹包問題ci

[編程題] 創造新世界
衆所周知計算機代碼底層計算都是0和1的計算,牛牛知道這點以後就想使用0和1創造一個新世界!牛牛如今手裏有n個0和m個1,給出牛牛能夠創造的x種物品,每種物品都由一個01串表示。牛牛想知道當前手中的0和1能夠最多創造出多少種物品。 
輸入描述:
輸入數據包括x+1行:
第一行包括三個整數x(2 ≤ x ≤ 20),n(0 ≤ n ≤ 500),m(0 ≤ m ≤ 500),以空格分隔
接下來的x行,每行一個01串item[i],表示第i個物品。每一個物品的長度length(1 ≤ length ≤ 50)


輸出描述:
輸出一個整數,表示牛牛最多能創造多少種物品

輸入例子:
3 3 1
1
00
100

輸出例子:
2
 1 #include "iostream"
 2 #include "string"
 3 #include "vector"
 4 #include "algorithm"
 5 
 6 using namespace std;
 7 
 8 int dp[505][505];
 9 int LL0[505], LL1[505];
10 int x, n, m;
11 
12 int main()
13 {
14     while (cin >> x >> n >> m)
15     {
16         for (int i = 0; i < x; i++)
17         {
18             string str;
19             cin >> str;
20             int l = str.length(), L0 = 0, L1 = 0;
21             for (int i = 0; i < l; i++)
22             {
23                 if (str[i] == '0')
24                     L0++;
25                 else
26                     L1++;
27             }
28             LL0[i + 1] = L0;
29             LL1[i + 1] = L1;
30         }
31         for (int i = 1; i <= x; i++)
32         {
33             for (int j = n; j >= LL0[i]; j--)//在這裏,揹包放入物品後,容量不斷的減小,直到再也放不進了    
34             {
35                 for (int k = m; k >= LL1[i]; k--)
36                     dp[j][k] = max(dp[j][k], dp[j - LL0[i]][k - LL1[i]] + 1);
37             }
38         }    
39         cout << dp[n][m] << endl;
40     }
41 }
42 
43 //3 3 1
44 //1
45 //00
46 //100
47 
48 //5 5 5
49 //1
50 //10
51 //00
52 //0
53 //0
相關文章
相關標籤/搜索