$f[i] 表示长度为i的最长上升子序列的最后一位的最小值是多少$
对于普通的$LIS我们可以二分确定位置去更新$
再来考虑对于这个,如果有某一位没有确定的话
那么这一位是可以随便取的,也就是说,所有的$f[i + 1] = min(f[i] + 1, f[i + 1])$
但是我们可以反过来想,这样相当于整体右移
那么我们维护一个$add 表示到此时有多少位不确定$
$如果这期间出现有确定的数,我们把这个数减去add,相当于把这一个数左移$
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 100010 5 int n; 6 int f[N]; 7 8 int main() 9 { 10 while (scanf("%d", &n) != EOF) 11 { 12 char op[10]; int x; 13 int add = 0, top = 0; 14 f[0] = -1e9; 15 for (int nn = 1; nn <= n; ++nn) 16 { 17 scanf("%s", op); 18 if (op[0] == 'K') 19 { 20 scanf("%d", &x); 21 if (f[top] < x - add) f[++top] = x - add; 22 else 23 { 24 int pos = lower_bound(f, f + 1 + top, x - add) - f - 1; 25 f[pos + 1] = min(f[pos + 1], x - add); 26 } 27 } 28 else ++add; 29 } 30 printf("%d ", top + add); 31 } 32 return 0; 33 }