琪露诺

Posted stephen-f

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了琪露诺相关的知识,希望对你有一定的参考价值。

传送门啦

本人第一个单调队列优化 $ dp $,不鼓励鼓励?

琪露诺这个题,$ dp $ 还是挺好想的对不,但是暴力 $ dp $ 的话会 $ TLE $ ,所以我们考虑用单调队列优化。

原题中说她只移动到区间 $ [i+L,i+R] $ 中的任意一格,所以我们单调队列在转移的时候 $ push $ 的应该是 $ dp[i-L] $ ,而不是 $ dp[i] $ ,对于每一段区间,我们用起点(队头)来更新答案就好了。

最后一步,因为区间的限制,我们只用在 $ [n-R+1,n] $ 中找一个最大值就好了。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 2 * 1e6;

inline int read(){
    char ch = getchar();
    int f = 1 , x = 0;
    while(ch > ‘9‘ || ch < ‘0‘){if(ch == ‘-‘)f = -1; ch = getchar();}
    while(ch >= ‘0‘ && ch <= ‘9‘){x = (x << 1) + (x << 3) + ch - ‘0‘;ch = getchar();}
    return x * f;
}

int n,L,R,a[maxn];
int f[maxn],q[maxn],head,tail;

int main(){
    n = read(); L = read(); R = read();
    for(int i=0;i<=n;i++){
        a[i] = read();
    }
    if(L > R) swap(L , R);
    head = tail = 1; q[1] = 0;
    for(int i=L;i<=n;i++){
        while(head <= tail && i - q[head] > R)
            head++;
        while(head <= tail && f[q[tail]] <= f[i-L])
            tail--;
        q[++tail] = i - L;
        f[i] = f[q[head]] + a[i];
    }
    int ans = 0;
    for(int i=n-R+1;i<=n;i++)
        ans = max(ans , f[i]);
    printf("%d
",ans);
    return 0;
}

以上是关于琪露诺的主要内容,如果未能解决你的问题,请参考以下文章

洛谷—— P1725 琪露诺

P1725 琪露诺

P1725 琪露诺

题解:琪露诺的冰雪小屋luogu3693

luogu P1725 琪露诺

luogu P1725 琪露诺