BZOJ 1109: [POI2007]堆積木Klo
阿新 • • 發佈:2019-01-22
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
分析
我們設
我們觀察一下三個限制條件
1.
2.
3.
我們按照
程式碼
#include <bits/stdc++.h>
#define N 1000100
using namespace std;
int read()
{
int x = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') f = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0'; ch = getchar();}
return x * f;
}
struct NOTE
{
int x,y;
friend bool operator < (NOTE a,NOTE b)
{
if (a.x == b.x)
return a.y < b.y;
return a.x < b.x;
}
}num[N];
int tot;
int p[N];
int main()
{
int n = read();
for (int i = 1; i <= n; i++)
{
int x = read();
if (x > i)
continue;
num[++tot].x = i - x;
num[tot].y = x;
}
std::sort(num + 1, num + tot + 1);
memset(p,127,sizeof(p));
int ans = 0;
for (int i = 1; i <= tot; i++)
{
int l = 1, r = ans, mn = 0;
while (l <= r)
{
int mid = (l + r) >> 1;
if (num[i].y > p[mid])
mn = mid, l = mid + 1;
else r = mid - 1;
}
ans = std::max(ans, mn + 1);
p[mn + 1] = std::min(p[mn + 1], num[i].y);
}
printf("%d\n",ans);
}