-
-
Notifications
You must be signed in to change notification settings - Fork 374
/
Copy pathknapsack.ts
54 lines (49 loc) · 1.8 KB
/
knapsack.ts
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
/**
* Solves the 0-1 Knapsack Problem.
* @param capacity Knapsack capacity
* @param weights Array of item weights
* @param values Array of item values
* @returns Maximum value subset such that sum of the weights of this subset is smaller than or equal to capacity
* @throws If weights and values arrays have different lengths
* @see [Knapsack](https://www.geeksforgeeks.org/0-1-knapsack-problem-dp-10/)
* @example knapsack(3, [3, 4, 5], [30, 50, 60]) // Output: 90
*/
export const knapsack = (
capacity: number,
weights: number[],
values: number[]
): number => {
if (weights.length !== values.length) {
throw new Error(
'Weights and values arrays should have the same number of elements'
)
}
const numberOfItems: number = weights.length
// Initializing a 2D array to store calculated states/values
const dp: number[][] = new Array(numberOfItems + 1)
.fill(0)
.map(() => new Array(capacity + 1).fill(0))
// Loop traversing each state of dp
for (let itemIndex = 1; itemIndex <= numberOfItems; itemIndex++) {
const weight = weights[itemIndex - 1]
const value = values[itemIndex - 1]
for (
let currentCapacity = 1;
currentCapacity <= capacity;
currentCapacity++
) {
if (weight <= currentCapacity) {
// Select the maximum value of including the current item or excluding it
dp[itemIndex][currentCapacity] = Math.max(
value + dp[itemIndex - 1][currentCapacity - weight],
dp[itemIndex - 1][currentCapacity]
)
} else {
// If the current item's weight exceeds the current capacity, exclude it
dp[itemIndex][currentCapacity] = dp[itemIndex - 1][currentCapacity]
}
}
}
// Return the final maximized value at the last position of the dp matrix
return dp[numberOfItems][capacity]
}