zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    springboot配置redis缓存
    【spark】local模式运行
    mybatis从入门到精通(二) 增删查改
    学习设计模式
    学习设计模式
    mybatis从入门到精通(一) 入门
    学习NIO 之 使用方法
    学习 NIO 之 零拷贝
    Java并发
    学习设计模式
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7055396.html
Copyright © 2011-2022 走看看