zoukankan      html  css  js  c++  java
  • bzoj1233 [Usaco2009Open]干草堆tower

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1233

    【题解】

    家里网络坏了一天。。。

    这题有个很神奇的结论:当底层最小的时候,一定有一种方案叠得最高。

    这样就可以dp了。又发现前缀和s是单调递减(从后往前),所以维护单调队列即可。

    注释里面是暴力。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    int n, a[M], s[M], f[M], g[M], m;
    int q[M];
    
    int main() {
        cin >> n;
        for (int i=1; i<=n; ++i) {
            scanf("%d", a+i);
            s[i] = s[i-1] + a[i];
        }
        int head = 1, tail = 0;
        q[++tail] = n+1;
        for (int i=n; i>=1; --i) {
            /*
            for (int j=i+1; j<=n+1; ++j)
                if(s[j-1] - s[i-1] >= f[j]) {
                    if(g[i] < g[j] + 1) {
                        g[i] = g[j] + 1;
                        f[i] = min(f[i], s[j-1] - s[i-1]);
                    }
                }
            */
            while(head < tail && s[q[head+1]-1] - f[q[head+1]] >= s[i-1]) ++head;
            f[i] = s[q[head]-1] - s[i-1];
            g[i] = g[q[head]] + 1;
            while(head <= tail && s[q[tail]-1] - f[q[tail]] < s[i-1] - f[i]) --tail;
            q[++tail] = i;
        }
        cout << g[1];
        return 0;
    }
    View Code
  • 相关阅读:
    Linux下的”锁“事儿
    拿得起,放得下,想得开
    关于TCP协议握手的那些事儿

    C++中的RTTI机制解析
    C/C++中产生随机数
    数据库-事务和锁
    JS 数组Array常用方法
    C# 压缩 SharpZipLib
    正则表达式学习3-负向零宽断言
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj1233.html
Copyright © 2011-2022 走看看