📜  K人的活动选择问题

📅  最后修改于: 2021-05-17 16:18:27             🧑  作者: Mango

给定两个数组S []E [] ,它们的大小N表示商店的开始和关闭时间,整数K表示人数,任务是找出他们可以访问的商店总数根据以下条件最佳地访问每个商店:

  • 只能由一个人参观一家商店
  • 如果某人的时间与其他人冲突,则该人无法访问该商店

例子:

方法:可以使用称为活动选择和排序的贪婪技术解决此问题。在活动选择问题中,只有一个人执行活动,但是这里有K个人可以进行一项活动。为了管理一个人的可用性,使用了多组。

请按照以下步骤解决问题:

  1. 初始化成对的数组a []并为每个索引i存储对{S [i],E [i]}
  2. 根据结束时间对数组a []进行排序。
  3. 初始化多重集st来存储人员以及他们当前正在访问的商店的结束时间。
  4. 0初始化变量ans以存储最终结果。
  5. 遍历每对数组a []
    1. 如果一个人可用,即a [i] .first大于或等于多重集合st中任何一个人的结束时间,则将计数增加1并用新的a [i]更新该元素的结束时间。第二
    2. 否则,继续检查下一对。
  6. 最后,将结果打印为count

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Comparator
bool compareBy(const pair& a,
               const pair& 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 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 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;
}


Python3
# 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


输出:
4

时间复杂度: O(NlogN)
辅助空间: O(N)