# 題目: UVa 10534 - Wavio Sequence

# 題目說明

給一個長度為n的整數序列,求此序列的LISLDS相連最長為多少

LIS的結尾與LDS的開頭為同一個字
LIS的長度與LDS相同


INPUT:
每筆測資輸入一個整數n,代表序列長度
接下來輸入n個整數


OUTPUT:
輸出相同長度且相連的最大LISLDS的合

# 解題方法

若使用普通DP的方式找LISLDS會超時,所以使用greedy algorithm加速
分別找出LISLDS與每個元素的位置
( LDS的找法為反向做LIS )

之後設一個tLISLDS中比較小的開始尋找
LISLDS中的元素位置num1[i]num2[i]皆不小於t,則跳出

輸出答案為t * 2 - 1

更詳細關於LISLDS每個元素的位置
可以參考這篇

# 參考程式碼

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	int n;

	while (cin >> n)
	{
		vector<int> str(n);
		for (int i = 0; i < n; ++i) cin >> str[i];

		vector<int> lis;
		vector<int> lds;
		lis.emplace_back(str[0]);
		lds.emplace_back(str[n - 1]);

		vector<int> num1(n);
		vector<int> num2(n);
		num1[0] = 1;
		num2[n - 1] = 1;
		int cnt1 = 1;
		int cnt2 = 1;

		for (int i = 1; i < n; ++i)
		{
			//lis
			if (str[i] > lis.back())
			{
				lis.emplace_back(str[i]);
				num1[i] = ++cnt1;
			}
			else
			{
				auto it = lower_bound(lis.begin(), lis.end(), str[i]);
				*it = str[i];
				num1[i] = (it - lis.begin() + 1);
			}

			//lds
			int j = n - i - 1;
			if (str[j] > lds.back())
			{
				lds.emplace_back(str[j]);
				num2[j] = ++cnt2;
			}
			else
			{
				auto it = lower_bound(lds.begin(), lds.end(), str[j]);
				*it = str[j];
				num2[j] = (it - lds.begin() + 1);
			}
		}

		int t = min(cnt1, cnt2);

		for (; t > 0; --t) for (int i = 0; i < n; ++i)
			if (num1[i] >= t && num2[i] >= t) goto out;

	out:
		cout << t * 2 - 1 << "\n";
	}
}