【重做】导弹拦截(单调栈优化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 != '
')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
",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
",top);
55 return 0;
56 }
原文地址:https://www.cnblogs.com/Wangsheng5/p/13934135.html