DP:0-1揹包問題

【問題描述】ios

0-1揹包問題:有 N 個物品,物品 i 的重量爲整數 wi >=0,價值爲整數 vi >=0,揹包所能承受的最大重量爲整數 C。若是限定每種物品只能選擇0個或1個,求可裝的最大價值。
能夠用公式表示爲:
 【算法思路】

動態規劃法。咱們能夠想到這個問題具備最優子結構性質,假設(x1,x2,...,xn)是最優解,那麼在去除x1以後,剩下(x2,...,xn)確定是如下問題的最優解:算法

根據這個特徵能夠設計DP函數並推出遞歸關係。具體地,m(i,j)是揹包容量爲j,可選擇物品爲i,i+1,…,n時0-1揹包問題的最優值。由0-1揹包問題的最優子結構性質,則:函數

按着DP[N][C]的矩陣一個一個從 下 往 上 填就能夠了,最後的結果是 DP(1,C)。要輸出選取的樣本編號的時候能夠從前日後, DP(1,C)== DP(2,C),則x1=0,不然1,依次類推便可。spa

【代碼】設計

 1 #include<iostream>
 2 #include<algorithm>
 3 #include <stdio.h>
 4 #define MAXN 10000
 5 using namespace std;
 6 
 7 int W[MAXN];
 8 int V[MAXN];
 9 int DP[MAXN][MAXN]= {0};
10 
11 int knapsack(int C, int N, int W[], int V[], int DP[][MAXN])
12 {
13     int lackL = min(C, W[N]-1);
14     for(int j = 0; j <=lackL; j++) DP[N][j] = 0;
15     for(int j = W[N]; j <=C; j++) DP[N][j] = V[N];
16     for(int i = N - 1; i>=1; i--){
17         lackL = min(C, W[i]-1);
18         for(int j = 0; j <=lackL; j++) DP[i][j] = DP[i+1][j];
19         for(int j = W[i]; j <=C; j++){
20             DP[i][j] = max( DP[i+1][j], DP[i+1][j-W[i]] + V[i] );
21         }
22     }
23     return DP[1][C];
24 }
25 
26 int main()
27 {
28     int C, N;
29     cin >> C >> N;
30     for(int i = 1; i <=N; i++) {
31         cin >> W[i] >> V[i];
32     }
33     cout<<knapsack(C, N, W, V, DP)<<endl;
34 
35     return 0;
36 }

 

 【拓展】code

若是如今的物品重量weight和揹包容量C都是正整數,那麼當他們是實數時,如何改進算法知足問題呢?blog

待完善(算法設計與分析P73)遞歸

相關文章
相關標籤/搜索