标签:
题目大意
从前往后n + 1个数都是递增的,然后从递增的最大一个值达到最后都是递减的也是n个数总共2*n+1个数。给你一个值求最长的一个满足上面要求的序列。
思路:
从前往后求一次单调递增子序列,从后往前求一次单调递增子序列,每次记录下值然后记录最大值
代码:
#include<iostream> #include<cstdio> #include<map> #include<math.h> #include<cstring> #include<algorithm> #define INF 0x1f1f1f1f using namespace std; int main() { int n, i, a[10010]; while(scanf("%d",&n) != EOF) { for(i = 1; i <= n; i++) { scanf("%d",&a[i]); } int t1 = 0, t2 = 0; int dp1[10010], s[10010], dp2[10010]; memset(dp1, 0, sizeof(dp1)); memset(s, -1, sizeof(s)); int top = 0; s[0] = -INF; //从前往后求出单调递增子序列 for(i = 1; i <= n; i++) { if(a[i] > s[top]) { s[++top] = a[i]; dp1[i] = top; } else { int l = 1, r = top; while(l <= r) { int mid = (l + r) / 2; if(a[i] > s[mid]) { l = mid + 1; } else r = mid - 1; } s[l] = a[i]; dp1[i] = l; } if(dp1[i] > t1) t1 = dp1[i]; } memset(dp2, 0, sizeof(dp2)); memset(s, -1, sizeof(s)); top = 0; s[0] = -INF; //从后往前求出单调递增子序列 for(i = n; i > 0; i--) { if(a[i] > s[top]) { s[++top] = a[i]; dp2[i] = top; } else { int l = 1, r = top; while(l <= r) { int mid = (l + r) / 2; if(a[i] > s[mid]) { l = mid + 1; } else r = mid - 1; } s[l] = a[i]; dp2[i] = l; } if(dp2[i] > t2) t2 = dp2[i]; } int ans = 1,tem; //每次求最小值 for(int i = 1;i <= n;i++) { tem = min(dp1[i],dp2[i]); ans = max(tem*2-1,ans); } cout << ans << endl; } return 0; }
标签:
原文地址:http://blog.csdn.net/bmamb/article/details/51333262