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

    Description

    奶牛们讨厌黑暗。 为了调整牛棚顶的电灯的亮度,Bessie必须建一座干草堆使得她能够爬上去够到灯泡 。一共有N大包的干草(1<=N<=100000)(从1到N编号)依靠传送带连续的传输进牛棚来。第i包干草有一个 宽度W_i(1<=w_i<=10000)。所有的干草包的厚度和高度都为1. Bessie必须利用所有N包干草来建立起干草堆,并且按照他们进牛棚的顺序摆放。她可以相放多少包就放 多少包来建立起tower的地基(当然是紧紧的放在一行中)。接下来他可以放置下一个草包放在之前一级 的上方来建立新的一级。注意:每一级不能比下面的一级宽。她持续的这么放置,直到所有的草包都被安 置完成。她必须按顺序堆放,按照草包进入牛棚的顺序。说得更清楚一些:一旦她将一个草包放在第二级 ,她不能将接下来的草包放在地基上。 Bessie的目标是建立起最高的草包堆。

    Input

    第1行:一个单一的整数N。 第2~N+1行:一个单一的整数:W_i。

    Output

    第一行:一个单一的整数,表示Bessie可以建立的草包堆的最高高度。

    Sample Input

    3
    1
    2
    3

    Sample Output

    2
    输出说明:
    前两个(宽度为1和2的)放在底层,总宽度为3,在第二层放置宽度为3的。
    +----------+
    | 3 |
    +---+------+
    | 1 | 2 |
    +---+------+




    这怕不是考过...考试题然后翻过来?问问问...

    翻译一下题目,就是在一段序列里,尽可能多的划分出一些子区间,使得这些区间的长度单调不升。

    于是反过来,我们从n往1加,使得这些区间单调不降。

    于是,设f[i]为到第i块干草,所能达到的最大高度, g[i]为f[i]最优时最后一块的最小长度。

    所以f[i] = f[j] + 1 (sum[i] - sum[j] >= g[j])(i+1<=j<=n+1), sum是后缀和。

    如果上面的式子可以更新,那么g[i] = min(g[i], sum[i] - sum[j]);

    发现这样转移是n^2的,数据范围卡着不让过。

    所以我们优化一下。

    观察到的sum值对于i递减是递增的,所以对于上面的式子i往左移动, 它的j要么是不动,要么是往左移动。

    就从i+1开始扫到n+1,如果有可以更新的就更新然后退出。

    最后答案就是f[1]


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    inline int read(){
        int res = 0;char ch=getchar();
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
        return res;
    }
    int n;
    int a[200005];
    long long qzh[200005];
    int f[200005];
    long long g[200005];
    
    int main()
    {
        n = read();
        for (register int i = 1 ; i <= n ; i ++)
            a[i] = read();
        for (int i = n ; i >= 1 ; i --) qzh[i] = qzh[i+1] + a[i];
        memset(g, 0x3f, sizeof g);
        g[n+1] = 0;
        for (register int i = n ; i >= 1 ; i--)
        {
            for (register int j = i + 1 ; j <= n + 1 ; j ++)
            {
                if (qzh[i] - qzh[j] >= g[j]) 
                {
                    if (f[j] + 1 > f[i])
                    {
                        f[i] = f[j] + 1;
                        g[i] = min(g[i], qzh[i] - qzh[j]);
                        break;
                    }
                }
            }
        }
        cout << f[1];
        return 0;
    }

     $sum_{age=16}^{18} hardworking = success$

  • 相关阅读:
    url 记录
    tvm
    const flold
    spring
    java连接mysql数据库
    linux常用命令记录
    pikachu漏靶场洞测试
    Starting.....
    IOS App提交流程
    InApp Purchase(iap)快速指南
  • 原文地址:https://www.cnblogs.com/BriMon/p/9382676.html
Copyright © 2011-2022 走看看