Related Articles

Related Articles

Activity selection problem with K persons
  • Difficulty Level : Hard
  • Last Updated : 13 Jan, 2021

Given two arrays S[] and E[] of size N denoting starting and closing time of the shops and an integer value K denoting the number of people, the task is to find out the maximum number of shops they can visit in total if they visit each shop optimally based on the following conditions:

  • A shop can be visited by only one person
  • A person cannot visit another shop if its timing collide with it

Examples:

Input: S[] = {1, 8, 3, 2, 6}, E[] = {5, 10, 6, 5, 9}, K = 2
Output: 4
Explanation: One possible solution can be that first person visits the 1st and 5th shops meanwhile second person will visit 4th and 2nd shops.

Input: S[] = {1, 2, 3}, E[] = {3, 4, 5}, K = 2
Output: 3
Explanation: One possible solution can be that first person visits the 1st and 3rd shops meanwhile second person will visit 2nd shop. 

Approach: This problem can be solved using the greedy technique called activity selection and sorting. In the activity selection problem, only one person performs the activity but here K persons are available for one activity. To manage the availability of one person a multiset is used.



Follow the steps below to solve the problem:

  1. Initialize an array a[] of pairs and store the pair {S[i], E[i]} for each index i.
  2. Sort the array a[] according to the ending time.
  3. Initialize a multiset st to store the persons with ending time of shop they are currently visiting.
  4. Initialize a variable ans with 0 to store the final result.
  5. Traverse each pair of array a[],
    1. If a person is available i.e a[i].first is greater than or equal to the ending time of any person in the multiset st, then increment the count by 1 and update the ending time of that element with new a[i].second.
    2. Otherwise, continue checking the next pairs.
  6. Finally, print the result as count.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
  
#include <bits/stdc++.h>
using namespace std;
  
// Comparator
bool compareBy(const pair<int, int>& a,
               const pair<int, int>& b)
{
    if (a.second != b.second)
        return a.second < b.second;
    return a.first < b.first;
}
// Function to find maximum shops
// that can be visited by K persons
int maximumShops(int* opening, int* closing,
                 int n, int k)
{
    // Store opening and closing
    // time of shops
    pair<int, int> a[n];
  
    for (int i = 0; i < n; i++) {
        a[i].first = opening[i];
        a[i].second = closing[i];
    }
  
    // Sort the pair of array
    sort(a, a + n, compareBy);
  
    // Stores the result
    int count = 0;
  
    // Stores current number of persons visting
    // some shop with their ending time
    multiset<int> st;
  
    for (int i = 0; i < n; i++) {
  
        // Check if current shop can be
        // assigned to a person who's
        // already visiting any other shop
        bool flag = false;
  
        if (!st.empty()) {
  
            auto it = st.upper_bound(a[i].first);
  
            if (it != st.begin()) {
                it--;
  
                // Checks if there is any person whose
                // closing time <= current shop opening
                // time
                if (*it <= a[i].first) {
  
                    // Erase previous shop visited by the
                    // person satisfying the condition
                    st.erase(it);
  
                    // Insert new closing time of current
                    // shop for the person satisfying ṭhe
                    // condition
                    st.insert(a[i].second);
  
                    // Increment the count by one
                    count++;
  
                    flag = true;
                }
            }
        }
  
        // In case if no person have closing
        // time <= current shop opening time
        // but there are some persons left
        if (st.size() < k && flag == false) {
            st.insert(a[i].second);
            count++;
        }
    }
  
    // Finally print the ans
    return count;
}
  
// Driver Code
int main()
{
  
    // Given starting and ending time
    int S[] = { 1, 8, 3, 2, 6 };
    int E[] = { 5, 10, 6, 5, 9 };
  
    // Given K and N
    int K = 2, N = sizeof(S)
                   / sizeof(S[0]);
  
    // Function call
    cout << maximumShops(S, E, N, K) << endl;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
from bisect import bisect_left
  
# Function to find maximum shops
# that can be visited by K persons
def maximumShops(opening, closing, n,  k):
    
    # Store opening and closing
    # time of shops
    a = [[0, 0] for i in range(n)]
  
    for i in range(n):
        a[i][0] = opening[i]
        a[i][1] = closing[i]
  
    # Sort the pair of array
    a = sorted(a)
  
    # Stores the result
    count = 1
  
    # Stores current number of persons visting
    # some shop with their ending time
    st = {}
    for i in range(n):
  
        # Check if current shop can be
        # assigned to a person who's
        # already visiting any other shop
        flag = False
  
        if (len(st) == 0):
            ar = list(st.keys())
  
            it = bisect_left(ar, a[i][0])
  
            if (it != 0):
                it -= 1
  
                # Checks if there is any person whose
                # closing time <= current shop opening
                # time
                if (ar[it] <= a[i][0]):
  
                    # Erase previous shop visited by the
                    # person satisfying the condition
                    del st[it]
  
                    # Insert new closing time of current
                    # shop for the person satisfying ṭhe
                    # condition
                    st[a[i][1]] = 1
  
                    # Increment the count by one
                    count += 1
                    flag = True
  
        # In case if no person have closing
        # time <= current shop opening time
        # but there are some persons left
        if (len(st) < k and flag == False):
            st[a[i][1]] = 1
            count += 1
              
    # Finally pr the ans
    return count
  
# Driver Code
if __name__ == '__main__':
  
    # Given starting and ending time
    S = [1, 8, 3, 2, 6]
    E = [5, 10, 6, 5, 9]
  
    # Given K and N
    K,N = 2, len(S)
  
    # Function call
    print (maximumShops(S, E, N, K))
  
    # This code is contributed by mohit kumar 29

chevron_right


 
 

Output: 

4

 

 

Time complexity: O(NlogN)
Auxiliary Space: O(N)

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :