Skip to content
Related Articles
Open in App
Not now

Related Articles

Maximize profit by picking elements of different types with total weight K

Improve Article
Save Article
  • Difficulty Level : Medium
  • Last Updated : 06 Feb, 2023
Improve Article
Save Article

Given an array item[] representing type, weight, and profit of N items, the task is to maximize the profit by picking different types of elements (i.e., no two elements are of the same type) such that the total weight is at most pick atmost K.

Examples:

Input: item[] = [[1, 3, 13], [5, 1, 10], [2, 2, 1], [1, 4, 9], [4, 5, 11], [1, 5, 9] ], K = 6
Output: 24
Explanation: The maximum value obtained is 24. 
You can take items of type1 with a profit of 13 and type5 with a profit of 10 and type2 with a profit of 1. 
Hence the value = 13 + 10 + 1 = 24

Input: item[] = [[1, 3, 13], [5, 1, 10], [2, 2, 1], [1, 4, 9], [4, 5, 11], [1, 5, 9] ], K = 9
Output: 34
Explanation: The maximum value obtained is 34. 
You can take items of type1 with a profit of 13 and of type5 with a profit of 10 and type4 with a profit of 11. H
ence the value = 13 + 10 + 11 = 34

Approach: The problem can be solved using recursion based on the following idea:

For each element of the item, we are having two choices whether to take that particular item or not.

  • Case 1 – Pick Case: When the weight of the item present at item[index][1] is less than or equal to K as well as the item of that type has not been brought so far, the profit of that item will get add up in our total value and the total weight K will get reduced by the weight of the current item and type of that item will get add up to the set saying this type item had been taken.
  • Case 2 – Not Pick Case: When the item present at item[index] does not get included in the final result, no profit i.e. 0 will get added up in our total value.

You can include items if and only if the current item weight is less than or equal to the total weight available and an item of that type has not been brought so far.

Follow the steps mentioned below to implement the idea:

  • Create a recursive function.
  • For each call, there are two choices for the item as mentioned above.
  • Calculate the value of all possible cases as mentioned above.
  • The maximum among them is the required answer.

Below is the implementation of the above approach:

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function for calculating maximum profit.
int solve(int index, vector<vector<int> >& item,
          set<int> st, int K)
{
    if (K == 0)
        return 0;
    if (index == 0) {
        if (st.find(item[index][0]) == st.end()
            && item[index][1] <= K) {
            return item[index][2];
        }
        else
            return INT_MIN;
    }
 
    // Not picking case
    int not_pick = 0 + solve(index - 1, item, st, K);
    int pick = INT_MIN;
 
    // Picking case
    if (item[index][1] <= K
        && st.find(item[index][0]) == st.end()) {
        st.insert(item[index][0]);
 
        // Inserting into set indicating
        // this type of item has been taken
        pick = item[index][2]
               + solve(index - 1, item, st,
                       K - item[index][1]);
    }
 
    // Returning the maximum out of both cases.
    return max(pick, not_pick);
}
 
// Driver code
int main()
{
    vector<vector<int> > item
        = { { 1, 3, 13 }, { 5, 1, 10 }, { 2, 2, 1 }, { 1, 4, 9 }, { 4, 5, 11 }, { 1, 5, 9 } };
 
    int N = item.size(), K = 6;
 
    // defining set for having type records.
    set<int> st;
 
    // Function call
    cout << "Maximum value obtained: "
         << solve(N - 1, item, st, K);
 
    return 0;
}


Java




// Java code to implement the approach
import java.io.*;
import java.util.*;
 
class GFG {
 
  // Function for calculating maximum profit.
  static int solve(int index, int[][] item,
                   Set<Integer> st, int K)
  {
    if (K == 0)
      return 0;
    if (index == 0) {
      if (!st.contains(item[index][0])
          && item[index][1] <= K) {
        return item[index][2];
      }
      else
        return Integer.MIN_VALUE;
    }
 
    // Not picking case
    int notPick = 0 + solve(index - 1, item, st, K);
    int pick = Integer.MIN_VALUE;
 
    // Picking case
    if (item[index][1] <= K
        && !st.contains(item[index][0])) {
      st.add(item[index][0]);
 
      // Inserting into set indicating
      // this type of item has been taken
      pick = item[index][2]
        + solve(index - 1, item, st,
                K - item[index][1]);
    }
 
    // Returning the maximum out of both cases.
    return Math.max(pick, notPick);
  }
 
  // Driver code
  public static void main(String[] args)
  {
    int[][] item
      = { { 1, 3, 13 }, { 5, 1, 10 }, { 2, 2, 1 },
         { 1, 4, 9 },  { 4, 5, 11 }, { 1, 5, 9 } };
    int N = item.length, K = 6;
 
    // defining set for having type records.
    Set<Integer> st = new HashSet<>();
 
    // Function call
    System.out.println("Maximum value obtained: "
                       + (solve(N - 1, item, st, K) + 1));
  }
}
 
// This code is contributed by lokesh.


Python3




# Python code to implement the approach
 
from typing import List, Tuple
 
def solve(index: int, item: List[Tuple[int, int, int]], st: set, K: int) -> int:
    if K == 0:
        return 0
    if index == 0:
        if item[index][0] not in st and item[index][1] <= K:
            return item[index][2]
        else:
            return float("-inf")
 
    # Not picking case
    not_pick = 0 + solve(index - 1, item, st, K)
    pick = float("-inf")
 
    # Picking case
    if item[index][1] <= K and item[index][0] not in st:
        st.add(item[index][0])
        pick = item[index][2] + solve(index - 1, item, st, K - item[index][1])
        st.remove(item[index][0])
 
    # Returning the maximum out of both cases.
    return max(pick, not_pick)
 
 
# Driver code
if __name__ == "__main__":
    item = [ (1, 3, 13), (5, 1, 10), (2, 2, 1), (1, 4, 9), (4, 5, 11), (1, 5, 9) ]
 
    N = len(item)
    K = 6
 
    # defining set for having type records.
    st = set()
 
    # Function call
    print("Maximum value obtained: ", solve(N - 1, item, st, K))
 
# This code is contributed by Vikram_Shirsat


C#




// C# code to implement the approach
using System;
using System.Collections.Generic;
 
public class GFG
{
  // Function for calculating maximum profit.
  static int Solve(int index, List<List<int>> item,
                   HashSet<int> st, int K)
  {
    if (K == 0)
      return 0;
    if (index == 0)
    {
      if (st.Contains(item[index][0]) == false
          && item[index][1] <= K)
      {
        return item[index][2];
      }
      else
        return Int32.MinValue;
    }
 
    // Not picking case
    int not_pick = 0 + Solve(index - 1, item, st, K);
    int pick = Int32.MinValue;
 
    // Picking case
    if (item[index][1] <= K
        && st.Contains(item[index][0]) == false)
    {
      st.Add(item[index][0]);
 
      // Inserting into set indicating
      // this type of item has been taken
      pick = item[index][2]
        + Solve(index - 1, item, st,
                K - item[index][1]);
    }
 
    // Returning the maximum out of both cases.
    return Math.Max(pick, not_pick);
  }
 
  // Driver code
  public static void Main()
  {
    List<List<int>> item
      = new List<List<int>>() {
      new List<int> { 1, 3, 13 },
      new List<int> { 5, 1, 10 },
      new List<int> { 2, 2, 1 },
      new List<int> { 1, 4, 9 },
      new List<int> { 4, 5, 11 },
      new List<int> { 1, 5, 9 } };
 
    int N = item.Count, K = 6;
 
    // defining set for having type records.
    HashSet<int> st = new HashSet<int>();
 
    // Function call
    Console.Write("Maximum value obtained: "
                  + (Solve(N - 1, item, st, K)+1));
  }
}
 
// This code is contributed by ishankhandelwals.


Javascript




// JS code to implement the approach
 
const solve = (index, item, st, K) => {
  if (K === 0) return 0;
  if (index === 0) {
      if (!st.has(item[index][0]) && item[index][1] <= K) {
          return item[index][2];
      } else {
          return Number.MIN_VALUE;
      }
  }
 
  // Not picking case
  let not_pick = 0 + solve(index - 1, item, st, K);
  let pick = Number.MIN_VALUE;
 
  // Picking case
  if (item[index][1] <= K && !st.has(item[index][0])) {
      st.add(item[index][0]);
 
      // Inserting into set indicating
      // this type of item has been taken
      pick = item[index][2] + solve(index - 1, item, st, K - item[index][1]);
  }
 
  // Returning the maximum out of both cases.
  return Math.max(pick, not_pick);
}
 
// Driver code
let item = [[1, 3, 13], [5, 1, 10], [2, 2, 1], [1, 4, 9], [4, 5, 11], [1, 5, 9]];
let N = item.length, K = 6;
 
// defining set for having type records.
let st = new Set();
 
// Function call
console.log(`Maximum value obtained: ${solve(N - 1, item, st, K)+1}`);
 
// This code is contributed by ishankhandelwals.


Output

Maximum value obtained: 24

Time Complexity: O(2N)
Auxiliary Space: O(N)

Related Articles:


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!