!-- Loading 底层遮罩 -->

P5858 黄金圣剑

传送门   

思路

状态转移方程简单,但是细节较多的单调队列优化dp模板。由于正向遍历队列里含有未知量,因此只能选择倒序遍历来保证队列里都是已知量。有w的限制,每加一次原料需要在队头放入编号w来保证正确性(经验教训),同时处理窗口大小需要谨慎。 

代码

#include<iostream>
#include<algorithm>
#include<cstring>
#define maxn 5007
using namespace std;
long long n, w, s, arr[2][maxn], q[maxn], a;
int main(void)
{
    ios::sync_with_stdio(false);
    cin >> n >> w >> s >> a;
    memset(arr, 0x80, sizeof(arr));
    int cr = 0; arr[1][1] = a;
    for (int i = 2; i <= n; i++, cr ^= 1)
    {
        cin >> a;
        memset(arr[cr], 0x80, sizeof(arr[cr]));
        memset(q, 0x80, sizeof(q));
        int head = 0, tail = 0;
        q[tail++] = w;
        for (int j = w; j >= 1; j--)
        {
            while (head < tail && min(w, j + s - 1) < q[head])
                head++;
            while (head < tail && arr[cr ^ 1][q[tail - 1]] < arr[cr ^ 1][j - 1])
                tail--;
            q[tail++] = j - 1;
            arr[cr][j] = arr[cr ^ 1][q[head]] + a * j;
        }
    }
    long long ans = INT64_MIN;
    for (int i = 1; i <= w; i++)
        ans = max(ans, arr[cr ^ 1][i]);
    cout << ans << '\n';
    return 0;
}

 

posted @ 2022-03-30 19:47  Thinker-X  阅读(94)  评论(0)    收藏  举报