Open In App

Maximize the happiness of the groups on the Trip

Improve
Improve
Like Article
Like
Save
Share
Report

A trip to mystical land is going to be organized in ByteLand, the city of Bytes. Unfortunately, there are limited seats say A and there are N number of groups of people. Every group can have old person o, child c, man m and woman w. The organizing committee wants to maximize the happiness value of the trip. Happiness value of the trip is the sum of the happiness value of all the groups that are going. A group will go for the trip if every member can get a seat (Breaking a group is not a good thing). 

  1. The happiness of child c = 4
  2. The happiness of woman w = 3
  3. The happiness of man m = 2
  4. The happiness of the old person o = 1

The happiness of group G, H(G) = (sum of happiness of people in it) * (number of people in the group). 
The happiness of the group (‘coow’) = (4 + 1 + 1 + 3) * 4 = 36.
Given the groups and the total seating capacity, the task is to maximize the happiness and print the maximized happiness of the groups going on the trip.
Examples: 

Input: groups[] = {“mmo”, “oo”, “cmw”, “cc”, “c”}, A = 5 
Output: 43 
Pick these groups [‘cmw’, ‘cc’] to get the maximum profit of (4 + 2 + 3) * 3 + (4 + 4) * 2 = 43
Input: groups[] = {“ccc”, “oo”, “cm”, “mm”, “wwo”}, A = 10 
Output: 77 
 

Approach: The problem can be considered as a slight modification of the 0-1 knapsack problem. The total seats available can be considered as the size of the knapsack. The happiness of each group can be considered as the profit of each item and the number of people in each group can be considered as the weight of each item. Now similar to the dynamic programming approach for 0-1 knapsack problem apply dynamic programming here to get the maximum happiness.
Below is the implementation of the above approach: 

C++




// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the maximized happiness
int MaxHappiness(int A, int N, vector<string> v)
{
    string str;
 
    // Two arrays similar to
    // 0 1 knapsack problem
    int val[N], wt[N], c = 0;
    for (int i = 0; i < N; i++) {
        str = v[i];
 
        // To store the happiness
        // of the current group
        c = 0;
        for (int j = 0; str[j]; j++) {
 
            // Current person is a child
            if (str[j] == 'c')
                c += 4;
 
            // Woman
            else if (str[j] == 'w')
                c += 3;
 
            // Man
            else if (str[j] == 'm')
                c += 2;
 
            // Old person
            else
                c++;
        }
 
        // Group's happiness is the sum of happiness
        // of the people in the group multiplied by
        // the number of people
        c *= str.length();
        val[i] = c;
        wt[i] = str.length();
    }
 
    // Solution using 0 1 knapsack
    int k[N + 1][A + 1];
    for (int i = 0; i <= N; i++) {
        for (int w = 0; w <= A; w++) {
            if (i == 0 || w == 0)
                k[i][w] = 0;
            else if (wt[i - 1] <= w)
                k[i][w] = max(val[i - 1]
                                  + k[i - 1][w - wt[i - 1]],
                              k[i - 1][w]);
            else
                k[i][w] = k[i - 1][w];
        }
    }
    return k[N][A];
}
 
// Driver code
int main()
{
 
    // Number of seats
    int A = 5;
 
    // Groups
    vector<string> v = { "mmo", "oo", "cmw", "cc", "c" };
    int N = v.size();
    cout << MaxHappiness(A, N, v);
 
    return 0;
}


Java




// Java implementation of the approach
class GFG
{
    // Function to return the maximized happiness
    static int maxHappiness(int A, int N, String[] v)
    {
        String str;
 
        // Two arrays similar to
        // 0 1 knapsack problem
        int[] val = new int[N];
        int[] wt = new int[N];
        int c = 0;
        for (int i = 0; i < N; i++)
        {
            str = v[i];
 
            // To store the happiness
            // of the current group
            c = 0;
            for (int j = 0; j < str.length(); j++)
            {
                // Current person is a child
                if (str.charAt(j) == 'c')
                    c += 4;
 
                // Woman
                else if (str.charAt(j) == 'w')
                    c += 3;
 
                // Man
                else if (str.charAt(j) == 'm')
                    c += 2;
 
                // Old Person
                else
                    c++;
            }
 
            // Group's happiness is the sum of happiness
            // of the people in the group multiplie
            // the number of people
            c *= str.length();
            val[i] = c;
            wt[i] = str.length();
        }
 
        // Solution using 0 1 knapsack
        int[][] k = new int[N + 1][A + 1];
        for (int i = 0; i <= N; i++)
        {
            for (int w = 0; w <= A; w++)
            {
                if (i == 0 || w == 0)
                    k[i][w] = 0;
                else if (wt[i - 1] <= w)
                {
                    k[i][w] = Math.max(val[i - 1]+ k[i - 1][w - wt[i - 1]], k[i-1][w]);
                }
                else
                {
                    k[i][w] = k[i - 1][w];
                }
            }
        }
        return k[N][A];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        // Number of seats
        int A = 5;
 
        // Groups
        String[] v = { "mmo", "oo", "cmw", "cc", "c" };
        int N = v.length;
        System.out.println(maxHappiness(A, N, v));
    }
}
 
// This code is contributed by Vivek Kumar Singh


Python3




# Python3 implementation of the approach
import numpy as np
 
# Function to return the maximized happiness
def MaxHappiness(A, N, v) :
     
    # Two arrays similar to
    # 0 1 knapsack problem
    val = [0] * N; wt = [0] * N; c = 0;
     
    for i in range(N) :
        string = v[i];
 
        # To store the happiness
        # of the current group
        c = 0;
        for j in range(len(string)) :
 
            # Current person is a child
            if (string[j] == 'c') :
                c += 4;
 
            # Woman
            elif (string[j] == 'w') :
                c += 3;
 
            # Man
            elif (string[j] == 'm') :
                c += 2;
 
            # Old person
            else :
                c += 1;
 
        # Group's happiness is the sum of happiness
        # of the people in the group multiplied by
        # the number of people
        c *= len(string);
         
        val[i] = c;
         
        wt[i] = len(string);
 
    # Solution using 0 1 knapsack
    k = np.zeros((N + 1, A + 1))
     
    for i in range(N + 1) :
         
        for w in range(A + 1) :
            if (i == 0 or w == 0) :
                k[i][w] = 0;
            elif (wt[i - 1] <= w) :
                k[i][w] = max(val[i - 1] +
                                k[i - 1][w - wt[i - 1]],
                                k[i - 1][w]);
            else :
                k[i][w] = k[i - 1][w];
                 
    return k[N][A];
 
# Driver code
if __name__ == "__main__" :
 
    # Number of seats
    A = 5;
 
    # Groups
    v = [ "mmo", "oo", "cmw", "cc", "c" ];
     
    N = len(v);
    print(MaxHappiness(A, N, v));
     
# This code is contributed by AnkitRai01


C#




// C# implementation of the approach
using System;
 
class GFG
{
    // Function to return the maximized happiness
    static int maxHappiness(int A, int N,
                              String[] v)
    {
        String str;
 
        // Two arrays similar to
        // 0 1 knapsack problem
        int[] val = new int[N];
        int[] wt = new int[N];
        int c = 0;
        for (int i = 0; i < N; i++)
        {
            str = v[i];
 
            // To store the happiness
            // of the current group
            c = 0;
            for (int j = 0; j < str.Length; j++)
            {
                // Current person is a child
                if (str[j] == 'c')
                    c += 4;
 
                // Woman
                else if (str[j] == 'w')
                    c += 3;
 
                // Man
                else if (str[j] == 'm')
                    c += 2;
 
                // Old Person
                else
                    c++;
            }
 
            // Group's happiness is the sum of happiness
            // of the people in the group multiplie
            // the number of people
            c *= str.Length;
            val[i] = c;
            wt[i] = str.Length;
        }
 
        // Solution using 0 1 knapsack
        int[ , ] k = new int[N + 1, A + 1];
        for (int i = 0; i <= N; i++)
        {
            for (int w = 0; w <= A; w++)
            {
                if (i == 0 || w == 0)
                    k[i, w] = 0;
                else if (wt[i - 1] <= w)
                {
                    k[i, w] = Math.Max(val[i - 1]+
                                       k[i - 1, w - wt[i - 1]],
                                       k[i - 1, w]);
                }
                else
                {
                    k[i, w] = k[i - 1, w];
                }
            }
        }
        return k[N, A];
    }
 
    // Driver code
    public static void Main()
    {
        // Number of seats
        int A = 5;
 
        // Groups
        String[] v = { "mmo", "oo", "cmw", "cc", "c" };
        int N = v.Length;
        Console.WriteLine(maxHappiness(A, N, v));
    }
}
 
// This code is contributed by Mohit kumar 29


Javascript




<script>
 
// Javascript program for the above approach
 
// Function to return the maximized happiness
    function maxHappiness(A, N, v) {
     
        let str;
 
        // Two arrays similar to
        // 0 1 knapsack problem
        let val = Array.from({length: N}, (_, i) => 0);
        let wt = Array.from({length: N}, (_, i) => 0);
        let c = 0;
        for (let i = 0; i < N; i++)
        {
            str = v[i];
 
            // To store the happiness
            // of the current group
            c = 0;
            for (let j = 0; j < str.length; j++)
            {
                // Current person is a child
                if (str[j] == 'c')
                    c += 4;
 
                // Woman
                else if (str[j] == 'w')
                    c += 3;
 
                // Man
                else if (str[j] == 'm')
                    c += 2;
 
                // Old Person
                else
                    c++;
            }
 
            // Group's happiness is the sum of happiness
            // of the people in the group multiplie
            // the number of people
            c *= str.length;
            val[i] = c;
            wt[i] = str.length;
        }
 
        // Solution using 0 1 knapsack
        let k = new Array(N + 1);
        for (var i = 0; i < k.length; i++) {
            k[i] = new Array(2);
        }
         
        for (let i = 0; i <= N; i++)
        {
            for (let w = 0; w <= A; w++)
            {
                if (i == 0 || w == 0)
                    k[i][w] = 0;
                else if (wt[i - 1] <= w)
                {
                    k[i][w] = Math.max(val[i - 1]+ k[i - 1][w - wt[i - 1]], k[i-1][w]);
                }
                else
                {
                    k[i][w] = k[i - 1][w];
                }
            }
        }
        return k[N][A];
    }
 
 
// Driver Code
 
    // Number of seats
        let A = 5;
 
        // Groups
        let v = [ "mmo", "oo", "cmw", "cc", "c" ];
        let N = v.length;
        document.write(maxHappiness(A, N, v));
 
// This code is contributed by sanjoy_62.
</script>


Output

43

Time Complexity: O(N *(L + A))
Auxiliary Space: O(N * A), where N is the size of the vector of strings, L is the maximum length of a string in the vector and A is a given input.

Efficient approach : Space optimization

In previous approach the current value K[i][w] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

Implementation steps:

  • Create a 1D vector dp of size A+1 and initialize it with 0.
  • Set a base case by initializing the values of DP .
  • Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
  • Update Dp by iterating through subproblems
  • At last return and print the final answer stored in dp[A] .

Implementation:

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to return the maximized happiness
int MaxHappiness(int A, int N, vector<string> v)
{
    string str;
 
    // Two arrays similar to
    // 0 1 knapsack problem
    int val[N], wt[N], c = 0;
    for (int i = 0; i < N; i++) {
        str = v[i];
 
        // To store the happiness
        // of the current group
        c = 0;
        for (int j = 0; str[j]; j++) {
 
            // Current person is a child
            if (str[j] == 'c')
                c += 4;
 
            // Woman
            else if (str[j] == 'w')
                c += 3;
 
            // Man
            else if (str[j] == 'm')
                c += 2;
 
            // Old person
            else
                c++;
        }
 
        // Group's happiness is the sum of happiness
        // of the people in the group multiplied by
        // the number of people
        c *= str.length();
        val[i] = c;
        wt[i] = str.length();
    }
 
    // Solution using 0 1 knapsack
    vector<int> dp(A + 1 , 0);
 
    for (int i = 1; i <= N; i++) {
        for (int w = A; w >= wt[i - 1]; w--) {
            dp[w] = max(val[i - 1] + dp[w - wt[i - 1]], dp[w]);
        }
    }
    return dp[A];
}
 
// Driver code
int main()
{
 
    // Number of seats
    int A = 5;
 
    // Groups
    vector<string> v = { "mmo", "oo", "cmw", "cc", "c" };
    int N = v.size();
    cout << MaxHappiness(A, N, v);
 
    return 0;
}


Java




import java.util.*;
 
public class Main {
    public static int maxHappiness(int A, int N, List<String> v) {
        String str;
        int[] val = new int[N];
        int[] wt = new int[N];
        int c;
 
        for (int i = 0; i < N; i++) {
            str = v.get(i);
            c = 0;
 
            for (int j = 0; j < str.length(); j++) {
                char ch = str.charAt(j);
 
                if (ch == 'c')
                    c += 4;
                else if (ch == 'w')
                    c += 3;
                else if (ch == 'm')
                    c += 2;
                else
                    c++;
            }
 
            c *= str.length();
            val[i] = c;
            wt[i] = str.length();
        }
 
        int[] dp = new int[A + 1];
 
        for (int i = 1; i <= N; i++) {
            for (int w = A; w >= wt[i - 1]; w--) {
                dp[w] = Math.max(val[i - 1] + dp[w - wt[i - 1]], dp[w]);
            }
        }
 
        return dp[A];
    }
 
    public static void main(String[] args) {
        int A = 5;
        List<String> v = Arrays.asList("mmo", "oo", "cmw", "cc", "c");
        int N = v.size();
 
        System.out.println(maxHappiness(A, N, v));
    }
}


Python3




def MaxHappiness(A, N, v) -> int:
    # Two lists similar to 0-1 knapsack problem
    val = [0] * N
    wt = [0] * N
 
    for i in range(N):
        # To store the happiness of the current group
        c = 0
        for j in range(len(v[i])):
            # Current person is a child
            if v[i][j] == 'c':
                c += 4
 
            # Woman
            elif v[i][j] == 'w':
                c += 3
 
            # Man
            elif v[i][j] == 'm':
                c += 2
 
            # Old person
            else:
                c += 1
 
        # Group's happiness is the sum of happiness of the people
        # in the group multiplied by the number of people
        c *= len(v[i])
        val[i] = c
        wt[i] = len(v[i])
 
    # Solution using 0-1 knapsack
    dp = [0] * (A + 1)
 
    for i in range(1, N + 1):
        for w in range(A, wt[i - 1] - 1, -1):
            dp[w] = max(val[i - 1] + dp[w - wt[i - 1]], dp[w])
 
    return dp[A]
 
# Driver code
if __name__ == '__main__':
    # Number of seats
    A = 5
 
    # Groups
    v = ["mmo", "oo", "cmw", "cc", "c"]
    N = len(v)
    print(MaxHappiness(A, N, v))


C#




using System;
 
public class MainClass {
  public static int MaxHappiness(int A, int N, string[] v)
  {
 
    // Two arrays similar to 0-1 knapsack problem
    int[] val = new int[N];
    int[] wt = new int[N];
 
    for (int i = 0; i < N; i++) {
      // To store the happiness of the current group
      int c = 0;
      for (int j = 0; j < v[i].Length; j++) {
        // Current person is a child
        if (v[i][j] == 'c') {
          c += 4;
        }
        // Woman
        else if (v[i][j] == 'w') {
          c += 3;
        }
        // Man
        else if (v[i][j] == 'm') {
          c += 2;
        }
        // Old person
        else {
          c += 1;
        }
      }
 
      // Group's happiness is the sum of happiness of
      // the people in the group multiplied by the
      // number of people
      c *= v[i].Length;
      val[i] = c;
      wt[i] = v[i].Length;
    }
 
    // Solution using 0-1 knapsack
    int[] dp = new int[A + 1];
 
    for (int i = 1; i <= N; i++) {
      for (int w = A; w >= wt[i - 1]; w--) {
        dp[w] = Math.Max(
          val[i - 1] + dp[w - wt[i - 1]], dp[w]);
      }
    }
 
    return dp[A];
  }
 
  public static void Main()
  {
    // Number of seats
    int A = 5;
 
    // Groups
    string[] v = { "mmo", "oo", "cmw", "cc", "c" };
    int N = v.Length;
    Console.WriteLine(
      MaxHappiness(A, N, v)); // Output: 21
  }
}


Javascript




// Function to return the maximized happiness
function MaxHappiness(A, N, v) {
    let val = [];
    let wt = [];
    let c = 0;
 
    for (let i = 0; i < N; i++) {
        let str = v[i];
 
        // To store the happiness of the current group
        c = 0;
        for (let j = 0; j < str.length; j++) {
 
            // Current person is a child
            if (str[j] === 'c')
                c += 4;
 
            // Woman
            else if (str[j] === 'w')
                c += 3;
 
            // Man
            else if (str[j] === 'm')
                c += 2;
 
            // Old person
            else
                c++;
        }
 
        // Group's happiness is the sum of happiness
        // of the people in the group multiplied by
        // the number of people
        c *= str.length;
        val[i] = c;
        wt[i] = str.length;
    }
 
    // Solution using 0/1 knapsack
    let dp = new Array(A + 1).fill(0);
 
    for (let i = 1; i <= N; i++) {
        for (let w = A; w >= wt[i - 1]; w--) {
            dp[w] = Math.max(val[i - 1] + dp[w - wt[i - 1]], dp[w]);
        }
    }
    return dp[A];
}
 
// Driver code
function main() {
    // Number of seats
    let A = 5;
 
    // Groups
    let v = ["mmo", "oo", "cmw", "cc", "c"];
    let N = v.length;
    console.log(MaxHappiness(A, N, v));
}
 
main();


Output

43

Time Complexity: O(N *(L + A))
Auxiliary Space: O(A)



Last Updated : 13 Sep, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads