📜  K 人的活动选择问题

📅  最后修改于: 2021-10-26 05:26:27             🧑  作者: Mango

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

  • 一个店铺只能一个人参观
  • 如果时间冲突,一个人不能访问另一家商店

例子:

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

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

  1. 初始化一个数组a[]并为每个索引i存储对{S[i], E[i]}
  2. 根据结束时间对数组a[] 进行排序。
  3. 初始化一个 multiset 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)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。