Skip to content

Commit 26ca371

Browse files
added another minimalItems knapcksack subset
1 parent 9f332b2 commit 26ca371

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package algorithms.dynamic
2+
3+
/// Minimal Items Knapsack Problem
4+
/// Given an array of positive weights and a target weight W,
5+
/// this function computes the minimum number of items needed to exactly reach weight W using dynamic programming.
6+
/// Each item may be used at most once.
7+
///
8+
/// dp(x) represents the minimal number of items required to achieve weight x.
9+
/// - Base case: dp(0) = 0 (no item is needed to achieve weight 0)
10+
/// - Recurrence: For each item with weight w and for each x from W down to w:
11+
/// if dp(x - w) is not INF then
12+
/// dp(x) = min(dp(x), dp(x - w) + 1)
13+
///
14+
/// Time Complexity: O(n * W), where n is the number of items.
15+
def minimalItems(weights: Array[Int], W: Int): (Int, Array[Int]) = {
16+
// Define INF as a value greater than any possible number of items (here: W + 1)
17+
val INF = W + 1
18+
// Initialize dp array: dp(x) stores the minimal number of items to reach weight x.
19+
val dp: Array[Int] = Array.fill(W + 1)(INF)
20+
dp(0) = 0
21+
22+
// Process each weight (item) exactly once.
23+
for (w <- weights) {
24+
// Iterate backwards to ensure each item is used only once.
25+
for (x <- W to w by -1) {
26+
if (dp(x - w) != INF) {
27+
dp(x) = math.min(dp(x), dp(x - w) + 1)
28+
}
29+
}
30+
}
31+
32+
// If dp(W) is still INF, there is no solution.
33+
val result = if (dp(W) == INF) -1 else dp(W)
34+
(result, dp)
35+
}
36+
37+
@main
38+
def mainMinimalItems(): Unit = {
39+
// Example: Items with weights 2, 5, 3, 6 and target weight W = 10.
40+
val weights: Array[Int] = Array(2, 5, 3, 6)
41+
val W = 10
42+
val (minItems, dp) = minimalItems(weights, W)
43+
44+
if (minItems == -1)
45+
println(s"Cannot exactly reach weight $W with the given items.")
46+
else
47+
println(s"Minimum number of items to exactly reach weight $W: $minItems")
48+
49+
println("DP Array (minimal number of items for each weight):")
50+
dp.zipWithIndex.foreach { case (items, weight) =>
51+
val info = if (items == W + 1) "not reachable" else items.toString
52+
println(s"Weight $weight: $info")
53+
}
54+
}

0 commit comments

Comments
 (0)