3 条题解

  • 0
    @ 2025-11-3 17:12:53

    要解决这个问题,我们需要找到一种方法,将传感器记录的时间点配对为进入时间和离开时间,使得在满足“同时在超市的人数不超过 k ”的约束下,所有人的总停留时间最大。

    问题分析

    传感器记录了 2n 个时间点( a_1 < a_2 < \dots < a_{2n} ),每个时间点对应一次“进入”或“离开”操作,但具体类型未知。我们的目标是合理配对这些时间点,使得:

    • 每个进入时间对应一个离开时间(进入时间 < 离开时间);
    • 任意时刻同时在超市的人数不超过 k ;
    • 所有配对的“离开时间 - 进入时间”之和最大。

    关键思路:贪心 + 栈模拟

    为了最大化总停留时间,我们需要让尽可能多的人在超市内停留尽可能长的时间,同时满足人数限制 k 。具体策略如下:

    1. 前 k 个时间点标记为“进入”:因为要先让 k 个人进入,才能开始计时。
    2. 后 k 个时间点标记为“离开”:因为要让最后 k 个人尽可能晚离开,以延长停留时间。
    3. 中间时间点交替标记:对于中间的时间点,交替标记为“进入”和“离开”,保证人数不超过 k 。
    4. 栈模拟配对:用栈存储“进入时间”,遇到“离开时间”时,弹出栈顶的“进入时间”,计算停留时间并累加。

    代码解析

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    
    void yy()
    {
        int n;
        cin >> n;
        int a[2 * n + 5];
        int b[2 * n + 5]; // 标记是否为进入时间,1表示进入,0表示离开
        int cnt = 0;
        int k;
        cin >> k;
        // 读取所有时间点
        for (int i = 1; i <= 2 * n; i++)
        {
            cin >> a[i];
        }
        // 组标记前k个为进入,后k个为离开,中间交替
        for (int i = 1; i <= 2 * n; i++)
        {
            if (i <= k)
            {
                b[i] = 1; // 前k个是进入
            }
            else if (i > 2 * n - k)
            {
                b[i] = 0; // 后k个是离开
            }
            else
            {
                b[i] = cnt % 2; // 中间交替
                cnt++;
            }
        }
        stack<int> st;
        int ans = 0;
        for (int i = 1; i <= 2 * n; i++)
        {
            if (b[i])
            {
                st.push(a[i]); // 进入时间入栈
            }
            else
            {
                ans += a[i] - st.top(); // 计算停留时间并累加
                st.pop();
            }
        }
        cout << ans << '\n';
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0), cout.tie(0);
        int t = 1;
        // cin >> t;
        while (t--)
            yy();
        return 0;
    }
    

    复杂度分析

    • 时间复杂度: O(n) ,其中 n 是输入的时间点对数( 2n 个时间点)。读取时间点、标记进入/离开、栈模拟配对的操作均为线性时间。
    • 空间复杂度: O(n) ,主要用于存储时间点数组和栈的空间。

    该方法通过贪心策略合理配对进入和离开时间,确保在人数限制下总停留时间最大,是解决该问题的高效方案。

    信息

    ID
    1176
    时间
    1000ms
    内存
    256MiB
    难度
    6
    标签
    (无)
    递交数
    107
    已通过
    36
    上传者