zoukankan      html  css  js  c++  java
  • 琪露诺 双端队列优化转移方程

    众所周知,琪露诺是以笨蛋闻名的冰之妖精。

    题目:https://www.luogu.org/problemnew/show/P1725

    显然,是一道DP题(很恶心显然二字,现在来恶心你们)

    状态转移是dp[i]=max(dp[k])+a[i];

    跳到当前位置的最大值是前面能跳到到这里的所有位置的最大值加上当前位置的冰冻值;

    为什么要用双端队列呢(因为爽啊)

    这个很裸了已经,滑动窗口的思想。就是纯DP是会T的,所以我们寻找最大值时要优化时间;

    如果当前的值比队列中的值大,就把队列中的已有元素弹出(因为我们是从前往后遍历的,一个位置在前且值小的元素是不会做出任何贡献的);

    代码

    #include<cstdio>
    #include<cstring>
    #include<deque>
    #include<algorithm>
    using namespace std;
    const int maxn=200100;
    struct node
    {
        int val;//DP最大值 
        int num;//
    };
    
    int n,a[maxn],l,r;
    int dp[maxn];
    deque <node> s;
    int main()
    {
        scanf("%d%d%d",&n,&l,&r);
        for(int i=0;i<=n;i++)
        {
            scanf("%d",a+i);
        }
        int tail=0;dp[tail]=0;
        node x;
        for(int i=l;i<=n;i++)//从0开始转移向l处 
        {
            while(s.size()&&dp[tail]>=s.back().val)
            {
                s.pop_back();
            }//无用值弹出 
            x.num=tail;x.val=dp[tail];
            s.push_back(x);//加入新值 
            if(tail-s.front().num>=(r-l+1)) s.pop_front();//队列的长度 
            dp[i]=s.front().val+a[i];//此时队列最前面的是前面能到达i的最大值 
            tail++;
        }
        int ans=-maxn;
        for(int i=n-r+1;i<=n;i++)
        {
            ans=max(ans,dp[i]);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    清除所有标签的属性
    chm提取
    视频分享
    依赖注入
    python-markdown
    light sdk
    ~
    html标签引入外部html
    微信公众平台自定义菜单
    还在为需要ajax而导入jquery吗? 纯js封装ajax操作
  • 原文地址:https://www.cnblogs.com/WHFF521/p/10960285.html
Copyright © 2011-2022 走看看