1 条题解

  • 1
    @ 2024-5-23 11:23:38

    用f[i]表示前i个人可以得到的最大效率值。那么可以枚举前i个人里面最后一个休息的人,设这个人是x,那么f[i]就等于第x+1到第i个人的效率值之和,加上f[x-1]。其中第一部分可以用前缀和来优化,设sum[i]表示从i到n的效率值之和,则第一部分可以表示为sum[x+1]-sum[i+1]。

    题目限定不能有连续的超过k个工人,相当于在i-k到i里面,选出使得f[x]+sum[x+1]-sum[i+1]最大的x,即滑动窗口求最值,可以用单调队列优化。

    需要注意,由于求最值的范围包括了i本身,因此循环到i时,需要先把i加入队列,再求最值。

    核心代码
    
    long long calc(int x)
    {
        return f[x - 1] + sum[x + 1];
    }
    int main()
    {
        cin >> n >> k;
        for (int i = 1; i <= n; i++)
            cin >> e[i];
        for (int i = n; i >= 1; i--)
            sum[i] = e[i] + sum[i + 1];
        q.push_back(0);
        for (int i = 1; i <= n; i++) {
            while (!q.empty() && i - q.front() > k)
                q.pop_front();
            while (!q.empty() && calc(q.back()) <= calc(i))
                q.pop_back();
            q.push_back(i);
            f[i] = f[max(q.front() - 1, 0)] + sum[q.front() + 1] - sum[i + 1];
        }
        cout << f[n];
        return 0;
    }
    
    • 1

    信息

    ID
    747
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    (无)
    递交数
    53
    已通过
    21
    上传者