BZOJ 1109: [POI2007]堆积木Klo
1109: [POI2007]堆积木Klo
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 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
1 1 2 5 4
Sample Output
3
HINT
Source
分析
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\n", low(tmp, tmp + n, inf) - tmp); 86 }
@Author: YouSiki