Unbounded Knapsack

Unbounded Knapsack

Unbounded Knapsack - DP on Subsequences

https://www.codingninjas.com/studio/problems/unbounded-knapsack_1215029?utm_source=striver&utm_medium=website&utm_campaign=a_zcoursetuf

My approach:

Since the sample space is infinite, we will use the same concept used in 'coin change' problem.

![image1](https://res.cloudinary.com/dx6m1kdeg/image/upload/v1709301398/Screenshot_2024-03-01_192515_d3kofd.png)

Code:

Memoization:

int helper(int i,int w, vector<int> &profit, vector<int> &weight, vector<vector<int>> &dp){

    if(i==0){
        if(weight[0]<=w){
            return profit[0]*(w/weight[0]);
        }
        return 0;
    }

    if(dp[i][w]!=-1){
        return dp[i][w];
    }

    int notTake = helper(i-1,w,profit,weight,dp);
    int take = 0;
    if(weight[i]<=w){
        take = profit[i]+helper(i,w-weight[i],profit,weight,dp);
    }

    dp[i][w] = max(notTake,take);
    return max(notTake,take);
}

int unboundedKnapsack(int n, int w, vector<int> &profit, vector<int> &weight){
    // Write Your Code Here.

    vector<vector<int>> dp(n, vector<int>(w+1, -1));
    return helper(n-1,w,profit, weight,dp);
}

Tabulation:

int unboundedKnapsack(int n, int w, vector<int> &profit, vector<int> &weight){
    // Write Your Code Here.

    vector<vector<int>> dp(n, vector<int>(w+1, 0));

    for(int i=weight[0];i<=w;i++){
        dp[0][i] = profit[0]*(i/weight[0]);
    }

    for(int i=1;i<n;i++){
        for(int j=1;j<=w;j++){
            int notTake = dp[i-1][j];
            int take = 0;
            if(j>=weight[i]){
                take = profit[i]+dp[i][j-weight[i]];
            }

            dp[i][j] = max(notTake,take);
        }
    }

    return dp[n-1][w];
}