# Unbounded Knapsack (Repetition of items allowed) | Set 2

Given an integer **W**, arrays **val[]** and **wt[]**, where **val[i]** and **wt[i]** are the values and weights of the i^{th} item, the task is to calculate the maximum value that can be obtained using weights not exceeding **W**.

**Note:** Each weight can be included multiple times.

**Examples:**

Input:W = 4, val[] = {6, 18}, wt[] = {2, 3}Output:18Explaination:The maximum value that can be obtained is 18, by selecting the 2^{nd}item twice.

Input:W = 50, val[] = {6, 18}, wt[] = {2, 3}Output:294

**Naive Approach:** Refer to the previous post to solve the problem using traditional Unbounded Knapsack algorithm.

**Time Complexity: **O(N * W)**Auxiliary Space: **O(W)

**Efficient Approach: ** The above approach can be optimized based on the following observations:

- Suppose the
**i**index gives us the maximum value per unit weight in the given data, which can be easily found in^{th}**O(n)**. - For any weight
**X**, greater than or equal to**wt[i]**, the maximum reachable value will be**dp[X – wt[i]] + val[i]**. - We can calculate the values of
**dp[]**from**0**to**wt[i]**using the traditional algorithm and we can also calculate the number of instances of**i**item we can fit in W weight.^{th} - So the required answer will be
**val[i] * (W/wt[i]) + dp[W%wt[i]]**.

Below is the implementation of new algorithm.

## Python3

`# Python Program to implement the above approach ` ` ` `from` `fractions ` `import` `Fraction ` ` ` `# Function to implement optimized ` `# Unbounded Knapsack algorithm ` `def` `unboundedKnapsackBetter(W, val, wt): ` ` ` ` ` `# Stores most dense item ` ` ` `maxDenseIndex ` `=` `0` ` ` ` ` `# Find the item with highest unit value ` ` ` `# (if two items have same unit value then choose the lighter item) ` ` ` `for` `i ` `in` `range` `(` `1` `, ` `len` `(val)): ` ` ` ` ` `if` `Fraction(val[i], wt[i]) \ ` ` ` `> Fraction(val[maxDenseIndex], wt[maxDenseIndex]) \ ` ` ` `or` `(Fraction(val[i], wt[i]) ` `=` `=` `Fraction(val[maxDenseIndex], wt[maxDenseIndex]) \ ` ` ` `and` `wt[i] < wt[maxDenseIndex] ): ` ` ` ` ` `maxDenseIndex ` `=` `i ` ` ` ` ` `dp ` `=` `[` `0` `for` `i ` `in` `range` `(W ` `+` `1` `)] ` ` ` ` ` `counter ` `=` `0` ` ` `breaked ` `=` `False` ` ` `for` `i ` `in` `range` `(W ` `+` `1` `): ` ` ` `for` `j ` `in` `range` `(` `len` `(wt)): ` ` ` ` ` `if` `(wt[j] <` `=` `i): ` ` ` `dp[i] ` `=` `max` `(dp[i], dp[i ` `-` `wt[j]] ` `+` `val[j]) ` ` ` ` ` `if` `i ` `-` `wt[maxDenseIndex] >` `=` `0` `\ ` ` ` `and` `dp[i] ` `-` `dp[i` `-` `wt[maxDenseIndex]] ` `=` `=` `val[maxDenseIndex]: ` ` ` ` ` `counter ` `+` `=` `1` ` ` ` ` `if` `counter>` `=` `wt[maxDenseIndex]: ` ` ` ` ` `breaked ` `=` `True` ` ` `# print(i) ` ` ` `break` ` ` `else` `: ` ` ` `counter ` `=` `0` ` ` ` ` `if` `not` `breaked: ` ` ` `return` `dp[W] ` ` ` `else` `: ` ` ` `start ` `=` `i ` `-` `wt[maxDenseIndex] ` `+` `1` ` ` `times ` `=` `(W ` `-` `start) ` `/` `/` `wt[maxDenseIndex] ` ` ` `index ` `=` `(W ` `-` `start) ` `%` `wt[maxDenseIndex] ` `+` `start ` ` ` `return` `(times ` `*` `val[maxDenseIndex] ` `+` `dp[index]) ` ` ` ` ` `# Driver Code ` `W ` `=` `100` `val ` `=` `[` `10` `, ` `30` `, ` `20` `] ` `wt ` `=` `[` `5` `, ` `10` `, ` `15` `] ` ` ` `print` `(unboundedKnapsackBetter(W, val, wt))` |

**Output:**

300

**Time Complexity**: O( N + min(wt[i], W) * N)**Auxiliary Space: **O(W)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the **DSA Self Paced Course** at a student-friendly price and become industry ready. To complete your preparation from learning a language to DS Algo and many more, please refer **Complete Interview Preparation Course****.**

In case you wish to attend **live classes **with experts, please refer **DSA Live Classes for Working Professionals **and **Competitive Programming Live for Students**.