【問題描述】ios
動態規劃法。咱們能夠想到這個問題具備最優子結構性質,假設(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)遞歸