n²誰都會打,不說了。算法
這裏討論一下nlogn算法(單調不減):ide
首先開始考慮單調性,我習慣性的覺得是單調隊列/棧優化的那個套路,想要找到一個跟下標有關的單調性卻發現沒有。優化
例如:我想過當下標增長時f[i]增長,後來發現了反例:1 3 4 2spa
事實上也沒有別的想獲得的了。code
我跑去看題解,發現單調性是這個毒瘤:blog
當單調不減子序列長度增長時,每一個長度對應的最小高度增長。隊列
而後每次二分出一個長度,保證最小高度恰好不大於a[i]string
而後用a[i]更新f[i]的最小高度...it
而後就沒啥難點了,A了。io
1 #include <cstdio> 2 #include <algorithm> 3 #include <cstring> 4 5 const int N = 100010; 6 7 int a[N], f[N], p[N], top; 8 9 inline int BS(int x) { 10 int l = 0, r = top, mid; 11 while(l < r) { 12 mid = (l + r + 1) >> 1; 13 if(p[mid] < x) { 14 r = mid - 1; 15 } 16 else { 17 l = mid; 18 } 19 } 20 return r; 21 } 22 23 inline int BS2(int x) { 24 int l = 0, r = top, mid; 25 while(l < r) { 26 mid = (l + r + 1) >> 1; 27 if(p[mid] >= x) { 28 r = mid - 1; 29 } 30 else { 31 l = mid; 32 } 33 } 34 return r; 35 } 36 37 int main() { 38 int n = 0, x; 39 while(scanf("%d", &x) != -1) { 40 a[++n] = x; 41 } 42 for(int i = 1; i <= n; i++) { 43 int t = BS(a[i]); 44 f[i] = t + 1; 45 p[f[i]] = std::max(p[f[i]], a[i]); 46 top = std::max(top, f[i]); 47 } 48 printf("%d \n", top); 49 top = 0; 50 memset(p, 0x7f, sizeof(p)); 51 for(int i = 1; i <= n; i++) { 52 int t = BS2(a[i]); 53 f[i] = t + 1; 54 p[f[i]] = std::min(p[f[i]], a[i]); 55 top = std::max(top, f[i]); 56 } 57 printf("%d", top); 58 return 0; 59 }
附一張提交記錄