题意:给定一个长度为n的整数序列,求一个最长子序列,使得该序列的长度为2*k+1,前k+1个数严格递增,后k+1个数严格递减。
分析:用O(nlogn)分别求出递增序列和递减序列,再O(n)求在某个位置符合条件的序列长度。
View Code
1 /* 2 Author:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <sstream> 8 #include <iostream> 9 #include <cmath> 10 #include <cstring> 11 #include <algorithm> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 #include <queue> 16 #include <stack> 17 #include <map> 18 #include <set> 19 using namespace std; 20 21 typedef long long ll; 22 #define DEBUG(x) cout<< #x << ':' << x << endl 23 #define REP(i,n) for(int i=0;i < (n);i++) 24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++) 25 #define PII pair<int,int> 26 #define PB push_back 27 #define MP make_pair 28 #define FI first 29 #define SE second 30 #define lowbit(x) (x&(-x)) 31 #define INF (1<<30) 32 33 const int maxn = 10011; 34 int a[maxn]; 35 int g1[maxn],g2[maxn]; 36 int d1[maxn],d2[maxn]; 37 int mx1[maxn],mx2[maxn]; 38 int main() 39 { 40 //freopen("in","r",stdin); 41 int n; 42 while(~scanf("%d",&n)) 43 { 44 for(int i=0;i<n;i++)scanf("%d",&a[i]); 45 for(int i=1;i<=n;i++)g1[i] = g2[i] = INF; 46 memset(mx1,0,sizeof(mx1)); 47 memset(mx2,0,sizeof(mx2)); 48 for(int i=0;i<n;i++) 49 { 50 int k = lower_bound(g1+1,g1+n+1,a[i]) - g1; 51 g1[k] = a[i]; 52 d1[i] = k; 53 } 54 for(int i=n-1;i>=0;i--) 55 { 56 int k = lower_bound(g2+1,g2+n+1,a[i]) - g2; 57 g2[k] = a[i]; 58 d2[i] = k; 59 } 60 mx1[0] = d1[0]; 61 for(int i=1;i<n;i++)mx1[i] = max(mx1[i-1],d1[i]); 62 for(int i=n-1;i>=0;i--)mx2[i] = max(mx2[i+1],d2[i]); 63 int ans = 0; 64 for(int i=0;i<n;i++) 65 { 66 int tmp = min(mx1[i],mx2[i]); 67 ans = max(ans,(tmp-1)*2+1); 68 //DEBUG(i); 69 //DEBUG(mx1[i]);DEBUG(mx2[i]);DEBUG(ans); 70 } 71 printf("%d\n",ans); 72 } 73 return 0; 74 }