【“盛大遊戲杯”第15屆上海大學程序設計聯賽 F】【LIS模板題】A序列

A序列

發佈時間: 2017年7月9日 18:17   最後更新: 2017年7月9日 21:05   時間限制: 1000ms   內存限制: 128M

如果一個序列有奇數個正整數組成,不妨令此序列爲a1,a2,a3,...,a2k+1(0<=k),並且a1,a2...ak+1是一個嚴格遞增的序列,ak+1,ak+2,...,a2k+1,是一個嚴格遞減的序列,則稱此序列是A序列。

比如1 2 5 4 3就是一個A序列。

現在Jazz有一個長度爲n的數組,他希望讓你求出這個數組所有滿足A序列定義的子序列裏面最大的那個長度。(子序列可以不連續)

比如1 2 5 4 3 6 7 8 9,最長的A序列子串是1 2 5 4 3。

多組輸入,每組兩行。
第一行是n,表示給的數組的長度。
第二行有n個數(int範圍),即給你的數組。
1<=n<=500000

每組輸入輸出一行,即最長的A序列子串的長度。

9
1 2 5 4 3 6 7 8 9

5


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x, y) memset(x, y, sizeof(x))
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b > a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b < a)a = b; }
const int N = 5e6 + 10, M = 0, Z = 1e9 + 7, inf = 0x3f3f3f3f;
template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a = (a + b) % Z; }
int casenum, casei;
int n;
int a[N], b[N], c[N], d[N], f[N];
int main()
{
	while (~scanf("%d", &n))
	{
		for (int i = 1; i <= n; ++i)
		{
			scanf("%d", &a[i]);
		}
		//算前
		int len = 0;
		for (int i = 1; i <= n; ++i)
		{
			if (a[i] > d[len])d[++len] = a[i], f[i] = len;
			else
			{
				int l = 1;
				int r = len;
				while (l < r)
				{
					int mid = (l + r) >> 1;
					if (a[i] <= d[mid])r = mid;
					else l = mid + 1;
				}
				d[l] = a[i];
				f[i] = l;
			}
		}
		memcpy(b, f, sizeof(b));
		//算後
		reverse(a + 1, a + n + 1);
		len = 0;
		for (int i = 1; i <= n; ++i)
		{
			if (a[i] > d[len])d[++len] = a[i], f[i] = len;
			else
			{
				int l = 1;
				int r = len;
				while (l < r)
				{
					int mid = (l + r) >> 1;
					if (a[i] <= d[mid])r = mid;
					else l = mid + 1;
				}
				d[l] = a[i];
				f[i] = l;
			}
		}
		memcpy(c, f, sizeof(c));
		reverse(c + 1, c + n + 1);
		//統計
		int ans = 1;
		for(int i = 1; i <= n; ++i)
		{
			int len = min(b[i], c[i]);
			gmax(ans, len * 2 - 1);
		}
		printf("%d\n", ans);
	}
	return 0;
}
/*
【分析】
LIS模板題

*/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章