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;
    }

    有木有很清爽啊~

  • 相关阅读:
    关于HTML标签
    windows bat 命令
    maven 基本用法
    idea 永久激活
    mysql 性能测试 mysqlslap 的使用介绍
    Javafx 入门教程(一)
    websocket server 服务端工具
    OPC 技术
    以http为例解读OSI七层协议
    Javafx 入门教程前言
  • 原文地址:https://www.cnblogs.com/backcl/p/13426301.html
Copyright © 2011-2022 走看看