• Luogu【P1725】琪露诺(单调队列,DP)


    本文是笔者第二篇解题报告。从现在开始,会将练的一些题发到博客上并归类到"解题报告"标签中。

    琪露诺是这样一道题

    这道题可以用纯DP做,但是据说会超时。(为什么?看起来过河这题比它数据大多了)于是到Luogu题解上找到了单调队列优化。

    首先讲一下纯DP思路

    假设我们的⑨正在河中央,编号为i的格子上。

    观察琪露诺的移动规律可得,琪露诺再往下走只能走到编号为i + l 到 i + r 之间的格子上。

    于是想到,琪露诺之所以现在能在这里,一定是上一步从编号为 i - r 到 i - l 的格子上其中一个,然后走过来。

    所以用 i 横扫输入数组,用 j 爆搜 i - r 到 i - l 之间的所有格子,然后取一个冰冻指数最大的。

    but这样会TLE 

    用单调队列。维护一个单调递减的队列,弹出队尾不符合性质的元素,弹出队首需要出队的元素,然后让当前元素进队,最后寻找答案。

    代码在这里

    #include<cstdio>
    #include<cctype>
    
    const int size=1000000;
    
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=(num<<1)+(num<<3)+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    int que[size],f[size],q[size];
    int h=1,t;
    int ans;
    
    int main(){
        int n=read(),l=read(),r=read();
        for(int i=0;i<=n;++i)    que[i]=read();
        for(int i=l;i<=n;++i){
            while(q[f[t]]<=q[i-l]&&t>=h)    t--;
            f[++t]=i-l;
            while(f[h]<i-r)    h++;
            q[i]=q[f[h]]+que[i];
        }
        ans=q[n-r+1];
        for(int i=n-r+2;i<=n;++i)    ans=ans>q[i]?ans:q[i];
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    运动员排成绩————————对多个数组进行排序
    关于指针 用字符数组,字符指针变量输入字符串 动态为字符型指针变量分配内存
    axel 原来求中点我想复杂了 两个结果一样
    Bezier曲线绘制 B样条绘制
    最大的回文子串
    字符数组
    按位与、或、异或等运算方法
    uniapp mixin 使用
    vue mixin执行覆盖
    windows10 安装NASM
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7055396.html
Copyright © 2020-2023  润新知