-
Notifications
You must be signed in to change notification settings - Fork 2
/
Binary knapsack.cpp
70 lines (54 loc) · 1.39 KB
/
Binary knapsack.cpp
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
/*8<
@Title:
Binary Knapsack (bottom up)
@Description:
Given the points each element have, and it
repespective cost, computes the maximum points
we can get if we can ignore/choose an element, in
such way that the sum of costs don't exceed the
maximum cost allowed.
@Time:
$O(N*W)$
@Space:
$O(N*W)$
@Warning:
The vectors $VS$ and $WS$ starts at one,
so it need an empty value at index 0.
>8*/
const int MAXN(1 '000), MAXCOST(1' 000 * 20);
ll dp[MAXN + 1][MAXCOST + 1];
bool ps[MAXN + 1][MAXCOST + 1];
pair<ll, vi> knapsack(const vll &points,
const vi &costs,
int maxCost) {
int n = len(points) -
1; // ELEMENTS START AT INDEX 1 !
for (int m = 0; m <= maxCost; m++) {
dp[0][m] = 0;
}
for (int i = 1; i <= n; i++) {
dp[i][0] = dp[i - 1][0] +
(costs[i] == 0) * points[i];
ps[i][0] = costs[i] == 0;
}
for (int i = 1; i <= n; i++) {
for (int m = 1; m <= maxCost; m++) {
dp[i][m] = dp[i - 1][m], ps[i][m] = 0;
int w = costs[i];
ll v = points[i];
if (w <= m and
dp[i - 1][m - w] + v > dp[i][m]) {
dp[i][m] = dp[i - 1][m - w] + v,
ps[i][m] = 1;
}
}
}
vi is;
for (int i = n, m = maxCost; i >= 1; --i) {
if (ps[i][m]) {
is.emplace_back(i);
m -= costs[i];
}
}
return {dp[n][maxCost], is};
}