1 #include <iostream> 2 #include <cstdlib> 3 #include<cstring> 4 using namespace std; 5 6 int max(int a, int b) 7 { 8 return (a >= b)? a : b; 9 } 10 11 int min(int a, int b) 12 { 13 return (a < b)? a : b; 14 } 15 16 void knapsack(int v[], int w[], int c, int n, int m[][20]) 17 { 18 //memset(m, 90, sizeof(m) ); 19 for(int j = 1; j <= c; j ++) 20 m[1][j] = 0; 21 22 int jMax = min(w[n] - 1, c); 23 for(int j = 0; j <= jMax; j ++) 24 m[n][j] = 0; 25 for(int j = w[n]; j <= c; j ++) 26 m[n][j] = v[n]; 27 28 //优化版:节省不必要的运算,第一行只需m[1][c]即可 29 /* 30 for(int i = n - 1; i > 1; -- i){ 31 jMax = min(w[i] - 1, c); 32 for(int j = 0; j <= jMax; ++j) 33 m[i][j] = m[i + 1][j]; 34 for(int j = w[i]; j <= c; ++j) 35 m[i][j] = max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]); 36 } 37 m[1][c] = m[2][c]; 38 if(c >= w[1]) 39 m[1][c] = max(m[1][c], m[2][c - w[1]] + v[1]); 40 */ 41 42 //配合可见表格版 43 for(int i = n - 1; i > 0; -- i){ 44 jMax = min(w[i] - 1, c); 45 for(int j = 0; j <= jMax; ++j) 46 m[i][j] = m[i + 1][j]; 47 for(int j = w[i]; j <= c; ++j) 48 m[i][j] = max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]); 49 } 50 51 for(int j = 0; j <= c; ++j){ 52 m[0][j] = 0; 53 }//为了配合课件的表格 54 for(int i = 0; i <= n; ++ i){ 55 for(int j = 0; j <= c; j ++){ 56 cout<<m[i][j]<<" "; 57 } 58 cout<<endl; 59 } 60 cout<<endl; 61 } 62 63 64 void traceback(int m[][20], int w[], int c, int n, int x[]) 65 { 66 for(int i = 1; i < n; ++ i) 67 if(m[i][c] == m[i + 1][c]) 68 x[i] = 0; 69 else{ 70 x[i] = 1; 71 c -= w[i]; 72 } 73 x[n] = (m[n][c]) ? 1 : 0; 74 } 75 76 int main() 77 { 78 int n, c, w[20], v[102], m[20][20], x[20]; 79 cout<<"n, c:"<<endl; 80 cin>>n>>c; 81 cout<<"Weight"<<endl; 82 for(int i = 1; i <= n; ++i){ 83 cin>>w[i]; 84 } 85 cout<<"Value"<<endl; 86 for(int i = 1; i <= n; ++i){ 87 cin>>v[i]; 88 } 89 90 knapsack(v, w, c, n, m); 91 traceback(m, w, c, n, x); 92 93 for(int i = 1; i <= n; ++i) 94 cout<<x[i]<<" "; 95 cout<<endl; 96 cout<<m[1][c]<<endl; 97 system("pause"); 98 }