zoukankan      html  css  js  c++  java
  • [Usaco2009 Open]干草堆

    来自一个弱鸡的随笔单调队列 动态规划

    题目链接:http://forioi.com/contest/problem?id=56&pid=9#problem-anchor

    g[j]<=s[i]-s[j],即s[j]+g[j]<=s[i],若有 k<j且g[k]+s[k]>=g[j]+s[j]则k永远不可能再转移别人了,因为如果k满足转移条件,那么j也会满足,而j的位置还更加靠后。

    因此,我们可以维护一个 g+s值单调递增的单调队列。

    每次转移时从单调队列中找到最后一个g[j]+s[j]<=s[i]的位置j,单调队列中j以左的元素从队首出队。

    转以后从队尾弹出g[j]+s[j]>=g[i]+s[i]的元素,然后将位置i加入单调队列。

    每个元素进出队列各一次,复杂度为O(n)。

    code:

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100005;
    int n,a[maxn],s[maxn],f[maxn],g[maxn],q[maxn],l,r;
    int main()
    {
        scanf("%d",&n);
        for(int i=n;i;--i)
            scanf("%d",a+i);
        for(int i=1;i<=n;++i)
            s[i]=s[i-1]+a[i];
        for(int i=1;i<=n;++i)
        {
            while(l<r&&s[q[l+1]]+g[q[l+1]]<=s[i])
                ++l;
            f[i]=f[q[l]]+1;
            g[i]=s[i]-s[q[l]];
            while(l<r&&s[q[r]]+g[q[r]]>=s[i]+g[i])
                --r;
            q[++r]=i;
        }
        printf("%d",f[n]); 
        return 0;
    }

    有木有很清爽啊~

  • 相关阅读:
    state estimation for robotics-1
    Linux命令----用户目录、路径
    Linux命令----系统目录结构
    Linux命令----shell
    socket php
    深入浅出讲解:php的socket通信 转
    phpstorm配置sftp自动上传
    linux下xdebug的安装和配置方法
    xdebug安装
    swoole 客户端和服务端不断通信
  • 原文地址:https://www.cnblogs.com/backcl/p/13426301.html
Copyright © 2011-2022 走看看