uva 10534 Wavio Sequence
题意:
给出一个数列,要求找出一个子序列,长度为2 * n + 1。
要求这个子序列的前n + 1个数为严格递增的,后n + 1个数为严格递减的。
求最长的这样一个子序列。
思路:
首先求出以每一个数结尾的最长上升子序列(从左到右)的长度inc和以每一个数结尾的最长上升子序列(从右到左)的长度dnc。
需要用nlogn的求法,不然TLE。
之后对于每一个数,子序列的长度是2 * min(inc[i],dnc[i]) - 1。
从这个里面找最大值即可。
代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <algorithm> 4 #include <iostream> 5 #include <string> 6 using namespace std; 7 const int N = 10005; 8 const int inf = 0x3f3f3f3f; 9 int a[N]; 10 int inc[N],dnc[N]; 11 int ans[N]; 12 int main() 13 { 14 int n; 15 while (scanf("%d",&n)!=EOF) 16 { 17 for (int i = 0;i < n;i++) scanf("%d",&a[i]); 18 memset(inc,0,sizeof(inc)); 19 memset(dnc,0,sizeof(dnc)); 20 int len = 1; 21 ans[len-1] = a[0]; 22 inc[0] = 1; 23 for (int i = 1;i < n;i++) 24 { 25 if (a[i] > ans[len-1]) 26 { 27 ans[len++] = a[i]; 28 inc[i] = len; 29 } 30 else 31 { 32 int pos = lower_bound(ans,ans+len,a[i]) - ans; 33 ans[pos] = a[i]; 34 inc[i] = len; 35 } 36 } 37 dnc[0] = 1; 38 len = 1; 39 ans[len-1] = a[n-1]; 40 for (int i = n - 2;i >= 0;i--) 41 { 42 if (a[i] > ans[len-1]) 43 { 44 ans[len++] = a[i]; 45 dnc[i] = len; 46 } 47 else 48 { 49 int pos = lower_bound(ans,ans+len,a[i]) - ans; 50 ans[pos] = a[i]; 51 dnc[i] = len; 52 } 53 } 54 int res = 0; 55 for (int i = 0;i < n;i++) 56 { 57 res = max(min(dnc[i],inc[i]) * 2 - 1,res); 58 } 59 printf("%d\n",res); 60 } 61 return 0; 62 }
康复训练中~欢迎交流!