Open In App

Maximum profit using M money and reducing half price of at most K stocks

Last Updated : 07 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given the cost[] and profit[] of N stocks and K tickets, the task is to find the maximum total profit that can be obtained from M initial amount of money using K tickets.

Note: A ticket can be used to reduce the cost of any stock to half of the original price and on a particular stock, a ticket can be used only once.

Examples:

Input: N = 3, cost[] = {2, 4, 5}, profit[] = {20, 17, 15}, K = 1, M = 4
Output: 37
Explanation: The most optimal case is when we take the 1st stock at regular cost and use a ticket for 2nd item. Total amount of money spent = (2 + (4 / 2)) = 4 ≤ M. Total Profit obtained is = 20 + 17 = 37

Input:  N = 3, cost[] = {4, 4, 3}, profit[] = {12, 14, 7}, K = 2, M = 5
Output: 26
Explanation: The most optimal case is when we take the 1st stock using the 1st ticket and the 2nd item using the 2nd ticket. Total amount of money spent = ((4 / 2) + (4 / 2)) = 4 ≤ M. Total Profit obtained is = 12 +14 = 26
 

Naive Approach: Implement the idea below to solve the problem:

It is always beneficial to use the maximum number of tickets because it will reduce the price of the stock. For each item there are 3 choices:

  • Don’t consider the current stock.
  • Take the current but don’t use the ticket.
  • Take the current and use the ticket.

Steps were taken to solve the problem:

  • Initialise the integer variable Ans for storing maximum profit earned.
  •  To consider all subsets of items, for a given element we have 3 choices:
    • Don’t take the current Stock, then the current amount left will be M, Ans remain the same.
    • If possible(M ≥ cost[i]), take the current stock and add its profit value to the Ans then the current money left will be  M – cost[i].
    • If the ticket is used, add its profit value to the Ans, then the current money left will be M – cost[i]/2.
  • Return maximum Ans of the above three possible cases.

Below is the code implementation of the above approach.

C++




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to calculate Maximum Profit
int maxProfit(int i, int N, int cost[],
              int profit[], int K, int M)
{
    if (i == N) {
        return 0;
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost,
                         profit, K, M);
 
    int ans2 = INT_MIN;
    int ans3 = INT_MIN;
 
    // If current stock can be taken
    // take it
    if (M >= cost[i]) {
        ans2 = profit[i]
               + maxProfit(i + 1, N, cost,
                           profit, K, M - cost[i]);
    }
 
    // If current stock can be taken
    // with ticket take it
    if (K > 0) {
        int newcost = cost[i] / 2;
        if (M >= newcost) {
            ans3 = profit[i]
                   + maxProfit(i + 1, N, cost, profit,
                               K - 1, M - newcost);
        }
    }
 
    // Returning maximum profit earned
    return max(ans1, max(ans2, ans3));
}
 
// Drivers code
int main()
{
    int cost[] = { 2, 4, 5 };
    int profit[] = { 20, 17, 15 };
    int N = sizeof(cost) / sizeof(cost[0]);
    int K = 1, M = 4;
 
    // Function call
    cout << maxProfit(0, N, cost, profit, K, M);
 
    return 0;
}


Java




// Java code for the above approach
import java.io.*;
 
class GFG {
 
  // Function to calculate Maximum profit
  static int maxProfit(int i, int N, int[] cost,
                       int[] profit, int K, int M)
  {
    if (i == N) {
      return 0;
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    int ans2 = Integer.MIN_VALUE;
    int ans3 = Integer.MIN_VALUE;
 
    // If current stock can be taken take it
    if (M >= cost[i]) {
      ans2 = profit[i]
        + maxProfit(i + 1, N, cost, profit, K,
                    M - cost[i]);
    }
 
    // If current stock can be taken with ticket take it
    if (K > 0) {
      int newcost = cost[i] / 2;
      if (M >= newcost) {
        ans3 = profit[i]
          + maxProfit(i + 1, N, cost, profit,
                      K - 1, M - newcost);
      }
    }
 
    // Returning maximum profit earned
    return Math.max(ans1, Math.max(ans2, ans3));
  }
 
  public static void main(String[] args)
  {
    int[] cost = { 2, 4, 5 };
    int[] profit = { 20, 17, 15 };
    int N = cost.length;
    int K = 1, M = 4;
 
    // Function call
    System.out.print(
      maxProfit(0, N, cost, profit, K, M));
  }
}
 
// This code is contributed by lokesh.


Python3




# Python code for the above approach
import sys
 
# Function to calculate Maximum Profit
def maxProfit(i,N,cost,profit,K,M):
    if(i==N):
        return 0
     
    # Don't take the current stock
    ans1=maxProfit(i+1,N,cost,profit,K,M)
     
    ans2 = -1*sys.maxsize
    ans3 = -1*sys.maxsize
     
    # If current stock can be taken
    # take it
    if(M >= cost[i]):
        ans2 = profit[i] + maxProfit(i + 1, N, cost, profit, K, M - cost[i])
     
    # If current stock can be taken
    # with ticket take it
    if(K > 0):
        newcost = cost[i]//2
        if(M >= newcost):
            ans3 = profit[i] + maxProfit(i + 1, N, cost, profit, K - 1, M - newcost)
     
    # Returning maximum profit earned
    return max(ans1, max(ans2, ans3))
     
# Driver code
cost = [2,4,5]
profit = [20,17,15]
N = len(cost)
K = 1
M = 4
 
# Function call
print(maxProfit(0, N, cost, profit, K, M))
 
# This code is contributed by Pushpesh Raj.


C#




// C# implementation
using System;
 
public class GFG {
 
  // Function to calculate Maximum Profit
  public static int maxProfit(int i, int N, int[] cost,
                              int[] profit, int K, int M)
  {
    if (i == N) {
      return 0;
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    int ans2 = Int32.MinValue;
    int ans3 = Int32.MinValue;
 
    // If current stock can be taken
    // take it
    if (M >= cost[i]) {
      ans2 = profit[i]
        + maxProfit(i + 1, N, cost, profit, K,
                    M - cost[i]);
    }
 
    // If current stock can be taken
    // with ticket take it
    if (K > 0) {
      int newcost = (int)(cost[i] / 2);
      if (M >= newcost) {
        ans3 = profit[i]
          + maxProfit(i + 1, N, cost, profit,
                      K - 1, M - newcost);
      }
    }
 
    // Returning maximum profit earned
    return Math.Max(ans1, Math.Max(ans2, ans3));
  }
 
  static public void Main()
  {
    int[] cost = { 2, 4, 5 };
    int[] profit = { 20, 17, 15 };
    int N = cost.Length;
    int K = 1, M = 4;
 
    // Function call
    Console.WriteLine(
      maxProfit(0, N, cost, profit, K, M));
  }
}
// This code is contributed by ksam24000.


Javascript




// javascript code for the above approach
 
// Function to calculate Maximum Profit
function maxProfit(i, N, cost,profit, K,  M)
{
    if (i == N) {
        return 0;
    }
 
    // Don't take the current stock
    let ans1 = maxProfit(i + 1, N, cost,
                         profit, K, M);
 
    let ans2 = Number.MIN_VALUE;
    let ans3 = Number.MIN_VALUE;
 
    // If current stock can be taken
    // take it
    if (M >= cost[i]) {
        ans2 = profit[i]
               + maxProfit(i + 1, N, cost,
                           profit, K, M - cost[i]);
    }
 
    // If current stock can be taken
    // with ticket take it
    if (K > 0) {
        let newcost = cost[i] / 2;
        if (M >= newcost) {
            ans3 = profit[i]
                   + maxProfit(i + 1, N, cost, profit,
                               K - 1, M - newcost);
        }
    }
 
    // Returning maximum profit earned
    return Math.max(ans1, Math.max(ans2, ans3));
}
 
// Drivers code
 
    let cost = [ 2, 4, 5 ];
    let profit = [ 20, 17, 15 ];
    let N = cost.length, K = 1, M = 4;
 
    // Function call
    console.log(maxProfit(0, N, cost, profit, K, M));
 
// This code is contributed by garg28harsh.


Output

37








Time Complexity = O(3N)
Auxiliary Space = O(1)

Efficient Approach using Dynamic Programming:

The above approach has overlapping subproblems as can be seem below. Say:

 M = 5, N = 3, K = 2, Cost[] = {4, 4, 3}, Profit[]={ 12, 14, 7}

Let X(M, 0, K) represent the given state that M initial money and K tickets and at index 0:

  • Left move – 1st case – Don’t take current element
  • Down move – 2nd case – Take the current element
  • Right move – 3rd case – Take the current element with Ticket.
The recursion tree for the test case

The recursion tree for the test case

So we can use the concept of dynamic programming.

Follow the steps mentioned below to implement the idea:

  • Initialize a 3D array (say dp[][][]) to store the value of each state as shown above.
  • Now use the same recursion as the previous approach.
  • To reduce the calculation, if a state which is already calculated is encountered, return the maximum profit for that state.
  • The value stored at the state (M, 0, K) is the required answer.

Below is the implementation of the efficient approach.

C++




// C++ implementation of the code
#include <bits/stdc++.h>
using namespace std;
 
// Initialize 3D dp
int dp[1001][501][11];
 
// Function to calculate Maximum profit
// earned
int maxProfit(int i, int N, int cost[], int profit[], int K,
              int M)
{
 
    if (i == N) {
        return 0;
    }
 
    // State of dp already calculated or not
    if (dp[M][i][K] != -1) {
        return dp[M][i][K];
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    int ans2 = INT_MIN;
    int ans3 = INT_MIN;
 
    // if current stock can be taken take it
    if (M >= cost[i]) {
        ans2 = profit[i]
               + maxProfit(i + 1, N, cost, profit, K,
                           M - cost[i]);
    }
 
    // if current stock can be taken with
    // ticket take it
    if (K > 0) {
        int newcost = cost[i] / 2;
        if (M >= newcost) {
            ans3 = profit[i]
                   + maxProfit(i + 1, N, cost, profit,
                               K - 1, M - newcost);
        }
    }
 
    // store the current dp state and return
    // the ans
    return dp[M][i][K] = max(ans1, max(ans2, ans3));
}
int main()
{
    // Number of stocks
    int N = 3;
    int cost[3] = { 2, 4, 5 };
    int profit[3] = { 20, 17, 15 };
 
    // Tickets to use
    int K = 1;
 
    // Current Money
    int M = 4;
 
    // Setting all values of dp array to -1
    memset(dp, -1, sizeof(dp));
 
    // Function call
    cout << maxProfit(0, N, cost, profit, K, M);
 
    return 0;
}


Java




// Java implementation of the code
import java.util.*;
 
public class GFG {
 
  // Initialize 3D dp
  static int dp[][][] = new int[1001][501][11];
 
  // Function to calculate Maximum profit
  // earned
  public static int maxProfit(int i, int N, int cost[],
                              int profit[], int K, int M)
  {
 
    if (i == N) {
      return 0;
    }
 
    // State of dp already calculated or not
    if (dp[M][i][K] != -1) {
      return dp[M][i][K];
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    int ans2 = Integer.MIN_VALUE;
    int ans3 = Integer.MIN_VALUE;
 
    // if current stock can be taken take it
    if (M >= cost[i]) {
      ans2 = profit[i]
        + maxProfit(i + 1, N, cost, profit, K,
                    M - cost[i]);
    }
 
    // if current stock can be taken with
    // ticket take it
    if (K > 0) {
      int newcost = cost[i] / 2;
      if (M >= newcost) {
        ans3 = profit[i]
          + maxProfit(i + 1, N, cost, profit,
                      K - 1, M - newcost);
      }
    }
 
    // store the current dp state and return
    // the ans
    return dp[M][i][K]
      = Math.max(ans1, Math.max(ans2, ans3));
  }
  public static void main(String args[])
  {
    // Number of stocks
    int N = 3;
    int cost[] = { 2, 4, 5 };
    int profit[] = { 20, 17, 15 };
 
    // Tickets to use
    int K = 1;
 
    // Current Money
    int M = 4;
 
    // Setting all values of dp array to -1
    for (int i = 0; i < 1001; i++) {
      for (int j = 0; j < 501; j++) {
        for (int k = 0; k < 11; k++) {
          dp[i][j][k] = -1;
        }
      }
    }
 
    // Function call
    System.out.println(
      maxProfit(0, N, cost, profit, K, M));
  }
}
 
//  This code is contributed by Samim Hossain Mondal.


Python3




# Python implementation of the code
 
# Initialize 3D dp
dp = [[[-1 for k in range(11)] for j in range(501)] for i in range(1001)]
 
# Function to calculate Maximum profit
# earned
def maxProfit(i, N, cost, profit, K, M):
    if i == N:
        return 0
 
    # State of dp already calculated or not
    if dp[M][i][K] != -1:
        return dp[M][i][K]
 
    # Don't take the current stock
    ans1 = maxProfit(i + 1, N, cost, profit, K, M)
 
    ans2 = float('-inf')
    ans3 = float('-inf')
 
    # if current stock can be taken take it
    if M >= cost[i]:
        ans2 = profit[i] + maxProfit(i + 1, N, cost, profit, K, M - cost[i])
 
    # if current stock can be taken with
    # ticket take it
    if K > 0:
        newcost = cost[i] // 2
        if M >= newcost:
            ans3 = profit[i] + maxProfit(i + 1, N, cost, profit, K - 1, M - newcost)
 
    # store the current dp state and return
    # the ans
    dp[M][i][K] = max(ans1, max(ans2, ans3))
    return dp[M][i][K]
 
# Number of stocks
N = 3
cost = [2, 4, 5]
profit = [20, 17, 15]
 
# Tickets to use
K = 1
 
# Current Money
M = 4
 
# Function call
print(maxProfit(0, N, cost, profit, K, M))
 
# This code is contributed by Harshad


C#




// C# implementation of the code
using System;
using System.Collections;
using System.Collections.Generic;
 
public class GFG {
 
  // Initialize 3D dp
  static int[, , ] dp = new int[1001, 501, 11];
 
  // Function to calculate Maximum profit
  // earned
  public static int maxProfit(int i, int N, int[] cost,
                              int[] profit, int K, int M)
  {
 
    if (i == N) {
      return 0;
    }
 
    // State of dp already calculated or not
    if (dp[M, i, K] != -1) {
      return dp[M, i, K];
    }
 
    // Don't take the current stock
    int ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    int ans2 = Int32.MinValue;
    int ans3 = Int32.MinValue;
 
    // if current stock can be taken take it
    if (M >= cost[i]) {
      ans2 = profit[i]
        + maxProfit(i + 1, N, cost, profit, K,
                    M - cost[i]);
    }
 
    // if current stock can be taken with
    // ticket take it
    if (K > 0) {
      int newcost = cost[i] / 2;
      if (M >= newcost) {
        ans3 = profit[i]
          + maxProfit(i + 1, N, cost, profit,
                      K - 1, M - newcost);
      }
    }
 
    // store the current dp state and return
    // the ans
    return dp[M, i, K]
      = Math.Max(ans1, Math.Max(ans2, ans3));
  }
  public static void Main(string[] args)
  {
    // Number of stocks
    int N = 3;
    int[] cost = { 2, 4, 5 };
    int[] profit = { 20, 17, 15 };
 
    // Tickets to use
    int K = 1;
 
    // Current Money
    int M = 4;
 
    // Setting all values of dp array to -1
    for (int i = 0; i < 1001; i++) {
      for (int j = 0; j < 501; j++) {
        for (int k = 0; k < 11; k++) {
          dp[i, j, k] = -1;
        }
      }
    }
 
    // Function call
    Console.WriteLine(
      maxProfit(0, N, cost, profit, K, M));
  }
}
 
// This code is contributed by Karandeep1234


Javascript




// Javascript implementation of the code
 
// Initialize 3D dp
let dp = Array(1001).fill().map(e => Array(501).fill().map(e => Array(11).fill(-1).map(e => e)));
 
// Function to calculate Maximum profit
// earned
function maxProfit(i, N, cost, profit, K, M)
{
 
    if (i == N) {
        return 0;
    }
 
    // State of dp already calculated or not
    if (dp[M][i][K] != -1) {
        return dp[M][i][K];
    }
 
    // Don't take the current stock
    let ans1 = maxProfit(i + 1, N, cost, profit, K, M);
 
    let ans2 = Number.MIN_SAFE_INTEGER;
    let ans3 = Number.MIN_SAFE_INTEGER;
 
    // if current stock can be taken take it
    if (M >= cost[i]) {
        ans2 = profit[i]
            + maxProfit(i + 1, N, cost, profit, K,
                        M - cost[i]);
    }
 
    // if current stock can be taken with
    // ticket take it
    if (K > 0) {
        let newcost = Math.floor(cost[i] / 2);
        if (M >= newcost) {
            ans3 = profit[i]
                + maxProfit(i + 1, N, cost, profit,
                            K - 1, M - newcost);
        }
    }
 
    // store the current dp state and return
    // the ans
    return dp[M][i][K] = Math.max(ans1, Math.max(ans2, ans3));
}
 
    // Number of stocks
    let N = 3;
    let cost = [ 2, 4, 5 ];
    let profit = [ 20, 17, 15 ];
 
    // Tickets to use
    let K = 1;
 
    // Current Money
    let M = 4;
 
    // Setting all values of dp array to -1
    for (let i = 0; i < 1001; i++) {
      for (let j = 0; j < 501; j++) {
        for (let k = 0; k < 11; k++) {
          dp[i][j][k] = -1;
        }
      }
    }
 
    // Function call
    console.log(maxProfit(0, N, cost, profit, K, M));
 
// This code is contributed by Utkarsh


Output

37








 Time Complexity: O(N*M*K)
 Auxiliary Space: O(N*M*K)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Implementation :

C++




#include <bits/stdc++.h>
using namespace std;
 
int maxProfit(int N, int K, int M, int cost[], int profit[]) {
    int dp[M+1][K+1][N+1]; // dp[M][K][i] stores max profit for M money, K tickets remaining, and ith stock
     
    // Initialize base cases
    for (int i = 0; i <= M; i++) {
        for (int j = 0; j <= K; j++) {
            for (int k = 0; k <= N; k++) {
                if (i == 0 || j == 0) {
                    dp[i][j][k] = 0;
                } else {
                    dp[i][j][k] = -1;
                }
            }
        }
    }
     
    // Perform bottom-up DP
    for (int i = N-1; i >= 0; i--) {
        for (int j = 0; j <= K; j++) {
            for (int k = 0; k <= M; k++) {
                int ans1 = dp[k][j][i+1]; // Don't take the current stock
                 
                int ans2 = INT_MIN;
                int ans3 = INT_MIN;
                 
                // if current stock can be taken, take it
                if (k >= cost[i]) {
                    ans2 = profit[i] + dp[k-cost[i]][j][i+1];
                }
                 
                // if current stock can be purchased with a ticket, take it using the ticket
                if (j > 0 && cost[i]/2 <= k) {
                    ans3 = profit[i] + dp[k-cost[i]/2][j-1][i+1];
                }
                 
                dp[k][j][i] = max(ans1, max(ans2, ans3));
            }
        }
    }
     
  // final answer
    return dp[M][K][0];
}
 
// Driver Code
int main() {
    int N = 3;
    int cost[3] = {2, 4, 5};
    int profit[3] = {20, 17, 15};
    int K = 1;
    int M = 4;
     
      // function call
    cout << maxProfit(N, K, M, cost, profit) << endl;
     
    return 0;
}
 
// -- by bhardwajji


Java




import java.io.*;
 
class GFG {
    static int maxProfit(int N, int K, int M, int cost[],
                         int profit[])
    {
        int[][][] dp = new int[M + 1][K + 1][N + 1];
        // dp[M][K][i] stores max profit
        // for M money, K tickets
        // remaining, and ith stock
 
        // Initialize base cases
        for (int i = 0; i <= M; i++) {
            for (int j = 0; j <= K; j++) {
                for (int k = 0; k <= N; k++) {
                    if (i == 0 || j == 0) {
                        dp[i][j][k] = 0;
                    }
                    else {
                        dp[i][j][k] = -1;
                    }
                }
            }
        }
 
        // Perform bottom-up DP
        for (int i = N - 1; i >= 0; i--) {
            for (int j = 0; j <= K; j++) {
                for (int k = 0; k <= M; k++) {
                    int ans1 = dp[k][j][i + 1];
                    // Don't take the
                    // current stock
 
                    int ans2 = Integer.MIN_VALUE;
                    int ans3 = Integer.MIN_VALUE;
 
                    // if current stock can be taken, take
                    // it
                    if (k >= cost[i]) {
                        ans2 = profit[i]
                               + dp[k - cost[i]][j][i + 1];
                    }
 
                    // if current stock can be purchased
                    // with a ticket, take it using the
                    // ticket
                    if (j > 0 && cost[i] / 2 <= k) {
                        ans3 = profit[i]
                               + dp[k - cost[i] / 2][j - 1]
                                   [i + 1];
                    }
 
                    dp[k][j][i] = Math.max(
                        ans1, Math.max(ans2, ans3));
                }
            }
        }
 
        // final answer
        return dp[M][K][0];
    }
    public static void main(String[] args)
    {
        int N = 3;
        int cost[] = { 2, 4, 5 };
        int profit[] = { 20, 17, 15 };
        int K = 1;
        int M = 4;
 
        // function call
        System.out.println(
            maxProfit(N, K, M, cost, profit));
    }
}


Python3




# Python implementation
def maxProfit(N, K, M, cost, profit):
    # dp[M][K][i] stores max profit for M money, K tickets remaining, and ith stock
    dp = [[[0 for _ in range(N+1)] for _ in range(K+1)] for _ in range(M+1)]
    # Initialize base cases
    for i in range(M+1):
        for j in range(K+1):
            for k in range(N+1):
                if i == 0 or j == 0:
                    dp[i][j][k] = 0
                else:
                    dp[i][j][k] = -1
 
    # Perform bottom-up DP
    for i in range(N-1, -1, -1):
        for j in range(K+1):
            for k in range(M+1):
                ans1 = dp[k][j][i+1] # Don't take the current stock
 
                ans2 = float('-inf')
                ans3 = float('-inf')
 
                # if current stock can be taken, take it
                if k >= cost[i]:
                    ans2 = profit[i] + dp[k-cost[i]][j][i+1]
 
                # if current stock can be purchased with a ticket, take it using the ticket
                if j > 0 and cost[i]//2 <= k:
                    ans3 = profit[i] + dp[k-cost[i]//2][j-1][i+1]
 
                dp[k][j][i] = max(ans1, max(ans2, ans3))
 
    # final answer
    return dp[M][K][0]
 
# Driver Code
N = 3
cost = [2, 4, 5]
profit = [20, 17, 15]
K = 1
M = 4
 
# function call
print(maxProfit(N, K, M, cost, profit))
 
# This code is contributed by Tapesh(tapeshdua420)


C#




using System;
 
public class GFG {
    public static int MaxProfit(int N, int K, int M,
                                int[] cost, int[] profit)
    {
        int[, , ] dp
            = new int[M + 1, K + 1,
                      N + 1]; // dp[M, K, i] stores max
                              // profit for M money, K
                              // tickets remaining, and ith
                              // stock
 
        // Initialize base cases
        for (int i = 0; i <= M; i++) {
            for (int j = 0; j <= K; j++) {
                for (int k = 0; k <= N; k++) {
                    if (i == 0 || j == 0) {
                        dp[i, j, k] = 0;
                    }
                    else {
                        dp[i, j, k] = -1;
                    }
                }
            }
        }
 
        // Perform bottom-up DP
        for (int i = N - 1; i >= 0; i--) {
            for (int j = 0; j <= K; j++) {
                for (int k = 0; k <= M; k++) {
                    int ans1
                        = dp[k, j, i + 1]; // Don't take the
                                           // current stock
 
                    int ans2 = int.MinValue;
                    int ans3 = int.MinValue;
 
                    // if current stock can be taken, take
                    // it
                    if (k >= cost[i]) {
                        ans2 = profit[i]
                               + dp[k - cost[i], j, i + 1];
                    }
 
                    // if current stock can be purchased
                    // with a ticket, take it using the
                    // ticket
                    if (j > 0 && cost[i] / 2 <= k) {
                        ans3 = profit[i]
                               + dp[k - cost[i] / 2, j - 1,
                                    i + 1];
                    }
 
                    dp[k, j, i] = Math.Max(
                        ans1, Math.Max(ans2, ans3));
                }
            }
        }
 
        // final answer
        return dp[M, K, 0];
    }
 
    public static void Main(string[] args)
    {
        int N = 3;
        int[] cost = { 2, 4, 5 };
        int[] profit = { 20, 17, 15 };
        int K = 1;
        int M = 4;
 
        // function call
        Console.WriteLine(MaxProfit(N, K, M, cost, profit));
    }
}


Javascript




function maxProfit(N, K, M, cost, profit) {
    const dp = new Array(M + 1);
 
    // Initialize the dp array
    for (let i = 0; i <= M; i++) {
        dp[i] = new Array(K + 1);
        for (let j = 0; j <= K; j++) {
            dp[i][j] = new Array(N + 1).fill(0);
        }
    }
 
    // Perform bottom-up DP
    for (let i = N - 1; i >= 0; i--) {
        for (let j = 0; j <= K; j++) {
            for (let k = 0; k <= M; k++) {
                const ans1 = dp[k][j][i + 1]; // Don't take the current stock
                let ans2 = -Infinity;
                let ans3 = -Infinity;
 
                // If the current stock can be taken, take it
                if (k >= cost[i]) {
                    ans2 = profit[i] + dp[k - cost[i]][j][i + 1];
                }
 
                // If the current stock can be purchased with a ticket, take it using the ticket
                if (j > 0 && cost[i] / 2 <= k) {
                    ans3 = profit[i] + dp[k - Math.floor(cost[i] / 2)][j - 1][i + 1];
                }
 
                dp[k][j][i] = Math.max(ans1, ans2, ans3);
            }
        }
    }
 
    // Final answer
    return dp[M][K][0];
}
 
// Driver Code
const N = 3;
const cost = [2, 4, 5];
const profit = [20, 17, 15];
const K = 1;
const M = 4;
 
// Function call
console.log(maxProfit(N, K, M, cost, profit));
 
// This code is contributed by Taranpreet Singh.


Output

37









Time Complexity: O(N*M*K)
Auxiliary Space: O(N*M*K)

Related articles:



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads