Найдите максимальное количество людей, которые могут присутствовать на собрании
Существует только одна комната, в которой проводятся N встреч, заданных в виде интервалов вида (начало[i], конец[i], люди[i]), где начало[i] — время начала i- й встречи, конец [i] — время окончания i -го собрания, people[i] — количество людей, которые могут присутствовать на i- м собрании. В любой момент времени комната может быть занята только одним собранием, т.е. если два собрания имеют перекрывающиеся интервалы, то можно выбрать только одно из них. Задача состоит в том, чтобы найти максимальное количество людей, которые могут присутствовать на собрании.
Примеры:
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.
Подход: проблема может быть решена с помощью динамического программирования на основе следующего наблюдения:
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.
Следуйте шагам, указанным ниже, чтобы реализовать идею:
- Сортируйте встречи по времени окончания встреч.
- Начните итерацию с начала отсортированного массива встреч.
- Для каждого индекса соблюдайте указанное выше соотношение.
- Если соседние интервалы перекрываются, используйте двоичный поиск в префиксе, чтобы найти j .
- Верните значение, хранящееся в dp[N-1], в качестве требуемого ответа.
Ниже приведена реализация описанного выше подхода.
C++
// C++ code to implement the approach#include <bits/stdc++.h>using namespace std;// Function to find the maximum number of peopleint 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 codeint 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 listclass 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 peopledef 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 codeMeetings=[[5,8,3],[1,4,5],[7,10,2]]N=len(Meetings)# Function callprint(maxPeople(Meetings,N))# This code is contributed by Pushpesh raj. |