zoukankan      html  css  js  c++  java
  • BZOJ 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 948  Solved: 341
    [Submit][Status][Discuss]

    Description

      Mary在她的生日礼物中有一些积木。那些积木都是相同大小的立方体。每个积木上面都有一个数。Mary用他的
    所有积木垒了一个高塔。妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置。一个上面写有数i
    的积木的正确位置是这个塔从下往上数第i个位置。Mary决定从现有的高塔中移走一些,使得有最多的积木在正确
    的位置。请你告诉Mary她应该移走哪些积木。

    Input

      第一行为一个数n,表示高塔的初始高度。第二行包含n个数a1,a2,...,an,表示从下到上每个积木上面的数。
    (1<=n<=100000,1<=ai<=1000000)。

    Output

      注意:请输出最多有多少点可以处在正确位置

    Sample Input

    5
    1 1 2 5 4

    Sample Output

    3

    HINT

     

    Source

     
    [Submit][Status][Discuss]

    分析

    OTZ Neighthorn

    一开始是三维——

    i > j && a[i] > a[j] && a[i] - i <= a[j] - j

    然后,巨机的Neighthorn告诉我们,这其实是二维,因为满足后两个条件时,第一维一定满足。

    所以是二维了——

    a[i] > a[j] && a[i] - i <= a[j] - j

    然而蒟蒻的我依然不会,于是巨机的Neighthorn有开始指点迷津。

    说,如果你把a[i]看作新的下标,这就是个水水的最长不严格上升子序列问题。

    ∑( 口 ||, 再次 OTZ Neighthorn。

    代码

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 #define lim 10000000
     6 
     7 class Scanner
     8 {
     9     private:
    10         char *c;
    11         
    12     public:
    13         Scanner(void)
    14         {
    15             c = new char[lim];
    16             fread(c, 1, lim, stdin);
    17         }
    18         
    19         int nextInt(void)
    20         {
    21             int res = 0;
    22             bool neg = 0;
    23             
    24             while (*c < '0')
    25                 if (*c++ == '-')
    26                     neg ^= true;
    27             
    28             while (*c >= '0')
    29                 res = res*10 + *c++ - '0';
    30                 
    31             return neg ? -res : res;
    32         }
    33 }in;
    34 
    35 #define N 1000005
    36 
    37 int n, a[N];
    38 
    39 struct pair
    40 {
    41     int x, y;
    42     pair(void) {};
    43     pair(int a, int b) :
    44         x(a), y(b) {};
    45 };
    46 
    47 pair p[N];
    48 
    49 int cmp(const void *a, const void *b)
    50 {
    51     if (((pair *)a)->x != ((pair *)b)->x)
    52         return ((pair *)a)->x - ((pair *)b)->x;
    53     else return -((pair *)a)->y + ((pair *)b)->y;
    54 }
    55 
    56 int tmp[N];
    57 
    58 #define inf 0x3f3f3f3f
    59 #define low lower_bound
    60 #define upp upper_bound
    61 
    62 signed main(void)
    63 {
    64     n = in.nextInt();
    65     
    66     for (int i = 1; i <= n; ++i)
    67         a[i] = in.nextInt();
    68         
    69     for (int i = 1; i <= n; ++i)if (a[i] <= i)
    70         p[i] = pair(a[i], i - a[i]);
    71     else p[i] = pair(inf, inf);
    72         
    73     qsort(p + 1, n, sizeof(pair), cmp);
    74     
    75     using namespace std;
    76     
    77     memset(tmp, inf, sizeof(tmp));
    78     
    79     for (int i = 1; i <= n; ++i)
    80     {
    81         int t = p[i].y;
    82         *upp(tmp, tmp + i, t) = t;
    83     }
    84     
    85     printf("%d
    ", low(tmp, tmp + n, inf) - tmp);
    86 }
    BZOJ_1109.cpp

    @Author: YouSiki

  • 相关阅读:
    设计模式之 观察者模式
    设计模式之 模板方法模式
    设计模式之 状态模式
    设计模式之 策略模式
    设计模式之 桥接模式
    设计模式之 外观模式
    设计模式之 代理模式
    设计模式之 装饰者模式
    设计模式之 适配器模式
    设计模式之 组合模式
  • 原文地址:https://www.cnblogs.com/yousiki/p/6091643.html
Copyright © 2011-2022 走看看