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 }