单调队列——P1725 琪露诺

题目含义

从坐标0开始,每次可以从i到i+l与i+r之间的位置

每次到新的位置,都可以获得新的位置对应的数

问还差一步就能到大于n的位置时,获得的最大数字

题目分析

dp[i]=max(dp[i-r]...dp[i-l])+a[i]

每次找最大就开一个数组用单调队列就好了(或者用一个优先队列

题目代码

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef long long LL;
const int maxn=2e5+7;
const int INF=0x3f3f3f3f;
int a[maxn],n,l,r,f[maxn],que[maxn];
int main(){
    scanf("%d%d%d",&n,&l,&r);
    for(int i=0;i<=n;i++)
        scanf("%d",&a[i]);
    f[0]=0;
    int head=1,tail=0;
    for(int i=l;i<=n;i++){
        while(head<=tail&&f[que[tail]]<=f[i-l])tail--;
        que[++tail]=i-l;
        while(head<=tail&&que[head]<i-r)head++;
        f[i]=f[que[head]]+a[i];
    }
    int ans=0;
    for(int i=n+1-r;i<=n;i++)
        ans=max(ans,f[i]);
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2019-07-26 20:14  helman78  阅读(136)  评论(0编辑  收藏  举报