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
K 1
N
K 2
K 3
Sample Output
3
【样例说明】
当序列为1 1 2 3 (也可以1 2 2 3,1 0 2 3……)
时最长上升子序列最长,为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 }