bzoj5427: 最长上升子序列

Description

现在给你一个长度为n的整数序列,其中有一些数已经模糊不清了,现在请你任意确定这些整数的值,
使得最长上升子序列最长。(为何最长呢?因为hxy向来对自己的rp很有信心)

Input

第一行一个正整数n
接下来n行第i行格式如下
K x:表示第i个数可以辨认且这个数为x
N:表示第i个数一个已经辨认不清了
n<=100000,|x|<=10^9

Output

一个正整数代表最长上升子序列最长是多少

Sample Input

4
K 1
N
K 2
K 3

Sample Output

3
【样例说明】
当序列为1 1 2 3 (也可以1 2 2 3,1 0 2 3……)
时最长上升子序列最长,为3
 
$f[i]$表示长度为$i$,最末尾的最小值。
对于不认识的,就是右移和整体加一。
认识的,就二分找一下就行了
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define M 100010
 4 int f[M];
 5 int main() {
 6     int n;
 7     scanf("%d", &n);
 8     int ad = 0;
 9     int L = 0, R = 0;
10     char s[20];
11     f[0] = -1000000001;
12     for(int i = 1; i <= n; ++ i) {
13         scanf("%s", s);
14         if(s[0] == 'K') {
15             int x;
16             scanf("%d", &x);
17             int l = L, r = R, t;
18             while(l <= r) {
19                 int mid = (l + r) / 2;
20                 if(f[mid] + ad < x) l = (t = mid) + 1;
21                 else r = mid - 1;
22             }
23             if(t == R) f[t + 1] = x - ad, ++ R;
24             else f[t + 1] = min(f[t + 1], x - ad);
25         }
26         else {
27             ++ ad;
28         }
29     }
30     printf("%d\n", ad + R);
31 }

 

posted @ 2018-08-28 19:34  iamunstoppable  阅读(427)  评论(0编辑  收藏  举报