Open In App

Find maximum number of people who can attend meeting

Last Updated : 05 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

There is only one room which is holding N meetings that are given as intervals of the form (start[i], end[i], people[i]) where start[i] is the starting time of the ith meeting, end[i] is the ending time of the ith meeting, people[i] is the number of people who can attend the ith meeting. At any point of time, the room can be occupied by only one meeting i.e., If two meetings have overlapping intervals then only one of them can be picked. The task is to find the maximum number of people who can attend the meeting.

Examples:

Input: Meetings = { {5, 8, 3}, {1, 4, 5}, {7, 10, 2} }
Outputs: 8
Explanation: The optimal meetings are {1, 4, 5} and {5, 8, 3}.
So, 5+3 = 8 is the maximum number of people.

Input: Meetings = { {1, 5, 20}, {3, 8, 50}.{6, 10, 70} }
Output: 90
Explanation: The optimal meetings are {1, 5, 20}, {6, 10, 70}.
So, 20 + 70 = 90 is the maximum number of people.

Approach: The problem can be solved using dynamic programming based on the below observation:

Process the meetings by sorting in a non-decreasing order of the end time as it is optimal to first process the meeting that gets over the earliest. We can use Dynamic Programming to solve this problem.

Create a dp[] array where dp[i] = maximum number of people who can attend the meeting till the ith meeting. At any particular point i, check if the ith meeting overlaps with the (i-1)th meeting. 

  • If there is no overlap dp[i] = dp[i-1] + people[i] ( maximum number of people possible till i-1 + people[i])
  • Otherwise, dp[i] = max( dp[i-1], dp[j] + people[i] ) (maximum number of people possible till i-1 or maximum number of people possible till some jth meeting which is nearest non-overlapping meeting with i where j < i.

We can use binary search to find j.

Follow the steps mentioned below to implement the idea:

  • Sort the meetings according to the end time of the meetings.
  • Start iterating from the start of the sorted array of meetings.
    • For each index follow the above mentioned relation.
    • If the adjacent intervals overlap, use binary search in the prefix to find the j.
  • Return the value stored at dp[N-1] as 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 to find the maximum number of people
int maxPeople(vector<vector<int> >& data, int n)
{
    // Sorting the intervals according to
    // the end time in non decreasing order
    sort(data.begin(), data.end(),
         [&](vector<int> a, vector<int> b) {
             if (a[1] == b[1])
                 return a[0] < b[0];
             else
                 return a[1] < b[1];
         });
 
    vector<int> dp(n, 0);
    dp[0] = data[0][2];
 
    // Need a map to store the highest possible value
    // for same end timed intervals
    map<int, int> mp;
 
    // First interval is assumed to be taken at first
    // the highest value with its ending time is dp[0]
    mp[data[0][1]] = dp[0];
    for (int i = 1; i < n; i++) {
        int curstart = data[i][0];
        int curend = data[i][1];
 
        // If the ith interval overlaps with
        // the (i-1)th interval
        if (curstart <= data[i - 1][1]) {
 
            // Binary search for an interval that has
            // its ending time just lesser than
            // the starting time of the ith interval
            int left = 0;
            int right = i;
            int var = data[i][0];
            while (left < right) {
                int mid = left + (right - left) / 2;
                if (data[mid][1] < var)
                    left = mid;
                else
                    right = mid - 1;
            }
            // We have two choice either we don't pick
            // the ith interval then dp[i-1] or we pick
            // the ith interval then dp[left]+ith value.
            // We use mp[data[left][1]] instead of
            // dp[left] since our map stores the maximum of
            // the dp values that end with a given end time.
            dp[i] = max(dp[i - 1],
                        mp[data[left][1]] + data[i][2]);
 
            // Update the map with max of current dp
            // value and mp[data[i][1]] accounting for an
            // interval that may have higher dp value ending
            // with the same end time as the ith interval.
            mp[data[i][1]] = max(dp[i], mp[data[i][1]]);
        }
        else {
            dp[i] = dp[i - 1] + data[i][2];
            mp[data[i][1]] = max(mp[data[i][1]], dp[i]);
        }
    }
 
    // Return the required answer
    return dp[n - 1];
}
 
// Driver code
int main()
{
    vector<vector<int> > Meetings
        = { { 5, 8, 3 }, { 1, 4, 5 }, { 7, 10, 2 } };
    int N = Meetings.size();
 
    // Function call
    cout << maxPeople(Meetings, N);
    return 0;
}


Java




/*package whatever //do not write package name here */
import java.io.*;
import java.util.*;
 
// sorting a list of list
class ListComparator<T extends Comparable<T> >
  implements Comparator<List<T> > {
 
  @Override public int compare(List<T> o1, List<T> o2)
  {
    for (int i = 0; i < Math.min(o1.size(), o2.size());
         i++) {
      int c = o1.get(i).compareTo(o2.get(i));
      if (c != 0) {
        return c;
      }
    }
    return Integer.compare(o1.size(), o2.size());
  }
}
 
class GFG {
 
  // Function to find the maximum number of people
  public static int maxPeople(List<List<Integer> > data,
                              int n)
  {
    // Sorting the intervals according to
    // the end time in non decreasing order
    Collections.sort(data, new ListComparator<>());
 
    List<Integer> dp = new ArrayList<Integer>();
    for (int i = 0; i < n; i++) {
      dp.add(0);
    }
    dp.set(0, data.get(0).get(2));
 
    // Need a map to store the highest possible value
    // for same end timed intervals
 
    Map<Integer, Integer> mp
      = new HashMap<Integer, Integer>();
 
    for (int i = 0; i < 15; i++) {
      mp.put(i, 0);
    }
 
    // First interval is assumed to be taken at first
    // the highest value with its ending time is dp[0]
    mp.put(data.get(0).get(1), dp.get(0));
    for (int i = 1; i < n; i++) {
      int curstart = data.get(i).get(0);
      int curend = data.get(i).get(1);
 
      // If the ith interval overlaps with
      // the (i-1)th interval
      if (curstart <= data.get(i - 1).get(1)) {
 
        // Binary search for an interval that has
        // its ending time just lesser than
        // the starting time of the ith interval
        int left = 0;
        int right = i;
        int var = data.get(i).get(0);
        while (left < right) {
          int mid = left + (right - left) / 2;
          if (data.get(mid).get(1) < var)
            left = mid;
          else
            right = mid - 1;
        }
        // We have two choice either we don't pick
        // the ith interval then dp[i-1] or we pick
        // the ith interval then dp[left]+ith value.
        // We use mp[data[left][1]] instead of
        // dp[left] since our map stores the maximum
        // of the dp values that end with a given
        // end time.
        dp.set(i, Math.max(
          dp.get(i - 1),
          mp.get(data.get(left).get(1))
          + data.get(i).get(2)));
 
        // Update the map with max of current dp
        // value and mp[data[i][1]] accounting for
        // an interval that may have higher dp value
        // ending with the same end time as the ith
        // interval.
        mp.put(
          data.get(i).get(1),
          Math.max(dp.get(i),
                   mp.get(data.get(i).get(1))));
      }
      else {
        dp.set(i,
               dp.get(i - 1) + data.get(i).get(2));
        mp.put(data.get(i).get(1),
               Math.max(mp.get(data.get(i).get(1)),
                        dp.get(i)));
      }
    }
 
    // Return the required answer
    return dp.get(n - 1);
  }
 
  public static void main(String[] args)
  {
    List<List<Integer> > Meetings = new ArrayList<>();
 
    List<Integer> a = new ArrayList<Integer>();
    a.add(5);
    a.add(8);
    a.add(3);
    Meetings.add(a);
 
    List<Integer> b = new ArrayList<Integer>();
    b.add(1);
    b.add(4);
    b.add(5);
    Meetings.add(b);
 
    List<Integer> c = new ArrayList<Integer>();
    c.add(7);
    c.add(10);
    c.add(2);
    Meetings.add(c);
 
    int N = Meetings.size();
 
    // Function call
    System.out.println(maxPeople(Meetings, N));
  }
}
 
// This code is contributed by akashish__


Python3




# Python code to implement the approach
 
# Function to find the maximum number of people
def maxPeople(data,n):
    # Sorting the intervals according to
    # the end time in non decreasing order
    data.sort(key=lambda a:a[1])
     
    dp=[0]*n
    dp[0]=data[0][2]
     
    # Need a map to store the highest possible value
    # for same end timed intervals
    mp=[0]*15
     
    # First interval is assumed to be taken at first
    # the highest value with its ending time is dp[0]
    mp[data[0][1]]=dp[0]
     
    for i in range(1,n):
        curstart=data[i][0]
        curend=data[i][1]
         
        # If the ith interval overlaps with
        # the (i-1)th interval
        if(curstart<=data[i-1][1]):
            # Binary search for an interval that has
            # its ending time just lesser than
            # the starting time of the ith interval
            left=0
            right=i
            var=data[i][0]
            while(left<right):
                mid=left+(right-left)//2
                if(data[mid][1]<var):
                    left=mid
                else:
                    right=mid-1
             
            # We have two choice either we don't pick
            # the ith interval then dp[i-1] or we pick
            # the ith interval then dp[left]+ith value.
            # We use mp[data[left][1]] instead of
            # dp[left] since our map stores the maximum of
            # the dp values that end with a given end time.
            dp[i]=max(dp[i-1],mp[data[left][1]]+data[i][2])
             
             
            # Update the map with max of current dp
            # value and mp[data[i][1]] accounting for an
            # interval that may have higher dp value ending
            # with the same end time as the ith interval.
            mp[data[i][1]]=max(dp[i],mp[data[i][1]])
             
         
        else:
            dp[i]=dp[i-1]+data[i][2]
            mp[data[i][1]]=max(mp[data[i][1]],dp[i])
             
    # Return the required answer
    return dp[n-1]
     
# Driver code
 
Meetings=[[5,8,3],[1,4,5],[7,10,2]]
N=len(Meetings)
 
# Function call
print(maxPeople(Meetings,N))
 
# This code is contributed by Pushpesh raj.


C#




using System;
using System.Collections.Generic;
 
public class GFG {
 
  public static int cmp(List<int> a, List<int> b)
  {
    if (a[1] == b[1]) {
      if (a[0] < b[0])
        return -1;
    }
    else {
      if (a[1] < b[1])
        return -1;
    }
    return 1;
  }
 
  // Function to find the maximum number of people
  public static int maxPeople(List<List<int> > data,
                              int n)
  {
    // Sorting the intervals according to
    // the end time in non decreasing order
    data.Sort(cmp);
 
    List<int> dp = new List<int>();
    for (int i = 0; i < n; i++) {
      dp.Add(0);
    }
    dp[0] = data[0][2];
 
    // Need a map to store the highest possible value
    // for same end timed intervals
    Dictionary<int, int> mp
      = new Dictionary<int, int>();
    for (int i = 0; i < 15; i++) {
      mp.Add(i, 0);
    }
 
    // First interval is assumed to be taken at first
    // the highest value with its ending time is dp[0]
    mp[data[0][1]] = dp[0];
    for (int i = 1; i < n; i++) {
      int curstart = data[i][0];
      int curend = data[i][1];
 
      // If the ith interval overlaps with
      // the (i-1)th interval
      if (curstart <= data[i - 1][1]) {
 
        // Binary search for an interval that has
        // its ending time just lesser than
        // the starting time of the ith interval
        int left = 0;
        int right = i;
        int var = data[i][0];
        while (left < right) {
          int mid = left + (right - left) / 2;
          if (data[mid][1] < var)
            left = mid;
          else
            right = mid - 1;
        }
        // We have two choice either we don't pick
        // the ith interval then dp[i-1] or we pick
        // the ith interval then dp[left]+ith value.
        // We use mp[data[left][1]] instead of
        // dp[left] since our map stores the maximum
        // of the dp values that end with a given
        // end time.
        dp[i]
          = Math.Max(dp[i - 1], mp[data[left][1]]
                     + data[i][2]);
 
        // Update the map with max of current dp
        // value and mp[data[i][1]] accounting for
        // an interval that may have higher dp value
        // ending with the same end time as the ith
        // interval.
        mp[data[i][1]]
          = Math.Max(dp[i], mp[data[i][1]]);
      }
      else {
        dp[i] = dp[i - 1] + data[i][2];
        mp[data[i][1]]
          = Math.Max(mp[data[i][1]], dp[i]);
      }
    }
 
    // Return the required answer
    return dp[n - 1];
  }
 
  static public void Main()
  {
    List<List<int> > Meetings = new List<List<int> >();
    Meetings.Add(new List<int>() { 5, 8, 3 });
    Meetings.Add(new List<int>() { 1, 4, 5 });
    Meetings.Add(new List<int>() { 7, 10, 2 });
    int N = Meetings.Count;
 
    // Function call
    Console.WriteLine(maxPeople(Meetings, N));
  }
}
 
// This code is contributed by akashish__


Javascript




function cmp(a, b) {
    if (a[1] == b[1]) {
        if (a[0] < b[0])
            return -1;
    }
    else {
        if (a[1] < b[1])
            return -1;
    }
    return 1;
}
 
// Function to find the maximum number of people
function maxPeople(data, n) {
    // Sorting the intervals according to
    // the end time in non decreasing order
    data.sort(cmp);
 
    let dp = [];
    for (let i = 0; i < n; i++) {
        dp.push(0);
    }
    dp[0] = data[0][2];
 
    // Need a map to store the highest possible value
    // for same end timed intervals
    let mp
        = new Map();
    for (let i = 0; i < 15; i++) {
        mp.set(i, 0);
    }
 
    // First interval is assumed to be taken at first
    // the highest value with its ending time is dp[0]
    mp[data[0][1]] = dp[0];
    for (let i = 1; i < n; i++) {
        let curstart = data[i][0];
        let curend = data[i][1];
 
        // If the ith interval overlaps with
        // the (i-1)th interval
        if (curstart <= data[i - 1][1]) {
 
            // Binary search for an interval that has
            // its ending time just lesser than
            // the starting time of the ith interval
            let left = 0;
            let right = i;
            let vari = data[i][0];
            while (left < right) {
                let mid = left + (right - left) / 2;
                if (data[mid][1] < vari)
                    left = mid;
                else
                    right = mid - 1;
            }
            // We have two choice either we don't pick
            // the ith interval then dp[i-1] or we pick
            // the ith interval then dp[left]+ith value.
            // We use mp[data[left][1]] instead of
            // dp[left] since our map stores the maximum
            // of the dp values that end with a given
            // end time.
            dp[i]
                = Math.max(dp[i - 1], mp.get(data[left][1])
                    + data[i][2]);
 
            // Update the map with max of current dp
            // value and mp[data[i][1]] accounting for
            // an interval that may have higher dp value
            // ending with the same end time as the ith
            // interval.
            mp.set(data[i][1], Math.max(dp[i], mp.get(data[i][1])));
        }
        else {
            dp[i] = dp[i - 1] + data[i][2];
            mp.set(data[i][1], Math.max(mp.get(data[i][1]), dp[i]));
        }
    }
 
    // Return the required answer
    return dp[n - 1];
}
 
let Meetings = [[5, 8, 3], [1, 4, 5], [7, 10, 2]];
let N = Meetings.length;
 
// Function call
console.log(maxPeople(Meetings, N));
 
// This code is contributed by akashish__


Output

8

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



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads