-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathKnapsack.java
142 lines (106 loc) · 2.75 KB
/
Knapsack.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package dp;
import java.util.Arrays;
public class Knapsack {
static int n;
static int[][] memo;
static int[] values;
static int[] weights;
public static void main(String[] args) {
// input
n = 4;
int w = 13;
values = new int[] { 100, 70, 50, 10 };
weights = new int[] { 10, 4, 6, 12 };
memo = new int[n+1][w+1];// +1 to avoid index out of bound error
// fill memo;
for (int[] e : memo)
Arrays.fill(e, -1);
// output
System.out.println(bruteForce(0, w)); // complexity: O(2^(n))
System.out.println(dp(0, w)); // complexity: O(2*(n*w))
/* Bottom-Up*/
// create the memo
int[][] bottomUp = new int[n+1][w+1];
// initialize the base case (no need here because array already initialized with zeroes)
/*for(int i = 0; i < 14; i++){
* bottomUp[4][i] = 0;
*}
*/
for(int idx = n-1; idx > -1; idx--) {
for (int remw = 0; remw < w+1; remw++) {
// compute results
int take = 0;
int leave = 0;
int ans = 0;
// take
if (remw >= weights[idx]) {
take = bottomUp[idx+1][remw - weights[idx]] + values[idx];
}
// leave
leave = bottomUp[idx+1][remw];
ans = Math.max(take, leave);
bottomUp[idx][remw] = ans;
}
}
System.out.println(bottomUp[0][w]);
/* The bottom up state trick which saves memory
would be implemented as follows:
bottomUp = new int[2][w+1];
for(int idx=n-1;idx>-1;idx--) {
for(int remw=0;remw<w+1;remw++) {
int take = 0;
int leave = 0;
int ans = 0;
// Take
if(remw>=weights[idx]) {
take = bottomUp[1][remw-weights[idx]] + values[idx];
}
// Leave
leave = bottomUp[1][remw];
ans = Math.max(take, leave);
bottomUp[0][remw] = ans;
}
for(int i=0;i<w+1;i++) {
bottomUp[1][i] = bottomUp[0][i];
}
}
*/
}
public static int bruteForce(int idx, int remw) {
if (idx == n)
return 0;
// compute results
int take = 0;
int leave = 0;
int ans = 0;
// take
if (remw >= weights[idx]) {
take = values[idx] + bruteForce(idx + 1, remw - weights[idx]);
}
// leave
leave = bruteForce(idx + 1, remw);
ans = Math.max(take, leave);
return ans;
}
public static int dp(int idx, int remw) {
if (idx == n)
return 0;
// Added line(already computed)
if (memo[idx][remw] != -1)
return memo[idx][remw];
// compute results
int take = 0;
int leave = 0;
int ans = 0;
// take
if (remw >= weights[idx]) {
take = values[idx] + dp(idx + 1, remw - weights[idx]);
}
// leave
leave = dp(idx + 1, remw);
ans = Math.max(take, leave);
// Added line(record results)
memo[idx][remw] = ans;
return ans;
}
}