【重做】导弹拦截(单调栈优化dp)
二分函数很容易写错(理解问题),需要仔细想一想。
1 #include<bits/stdc++.h> 2 #define rep(i,a,n) for(register int i = a;i <= n;++i) 3 #define per(i,n,a) for(register int i = n;i <= a;--i) 4 #define lb lower_bound 5 #define ub upper_bound 6 #define mid (l+r>>1) 7 using namespace std; 8 typedef long long ll; 9 10 const int Maxn = 1e5+10; 11 12 char c,l; 13 14 ll read(){ 15 ll a = 0;c = getchar(),l = c; 16 while(c < '0'||c > '9')l = c,c = getchar(); 17 while('0' <= c&&c <= '9')a = a*10+c-'0',c = getchar(); 18 if(l == '-')return -a;return a; 19 } 20 21 int a[Maxn],sx[Maxn]; 22 int n,top; 23 24 int work1(int x){ 25 int l = 1,r = top,ans = 1; 26 while(l <= r) 27 if(sx[mid] < x)ans = mid,r = mid-1; 28 else l = mid+1; 29 return ans; 30 } 31 32 int work2(int x){ 33 int l = 1,r = top,ans = 1; 34 while(l <= r) 35 if(sx[mid] >= x)ans = mid,r = mid-1; 36 else l = mid+1; 37 return ans; 38 } 39 40 int main(){ 41 // while(c != '\n')a[++n] = read(); 42 while(cin >> a[++n]);n--; 43 top = 1,sx[1] = a[1]; 44 rep(i,2,n){ 45 if(a[i] <= sx[top])sx[++top] = a[i]; 46 else sx[work1(a[i])] = a[i]; 47 } 48 printf("%d\n",top); 49 50 top = 1,sx[1] = a[1]; 51 rep(i,2,n) 52 if(a[i] > sx[top])sx[++top] = a[i]; 53 else sx[work2(a[i])] = a[i]; 54 printf("%d\n",top); 55 return 0; 56 }