[2018.11.03 T3] 單調序列

暫無鏈接

單調序列

GISPZJZ 有一個長度爲 nn 的序列a1,a2,,ana_1,a_2,…,a_n。序列的所有元素都是 11 或者22

我們稱一序列是該序列的不下降子序列p1,p2,,pkp_1,p_2,…,p_k,滿足 1p1<p2<p3<<pkn1≤p_1<p_2<p_3<…<p_k≤n,且 ap1ap2apna_{p_1}≤a_{p_2}≤…≤a_{p_n}

現在 GISPZJZ 可以選擇序列中的一段區間[L,R][L,R],然後將整段反轉,例如挑選區間[2,4][2,4], 可以將序列(a1,a2,a3,a4,a5)(a_1,a_2,a_3,a_4,a_5)變換爲(a1,a4,a3,a2,a5)(a_1,a_4,a_3,a_2,a_5)。在此基礎上,GISPZJZ 希望在反轉 後,序列的最長不下降子序列最長。當然,GISPZJZ 也可以選擇不反轉任何區間。現在要求求出最優情況下,序列的最長不下降子序列的長度。

輸入:

第一行一個正整數 nn

第二行 nn 個數,分別爲 a1,a2,,ana_1,a_2,…,a_n,滿足 1ai21≤a_i≤2

輸出:

一行一個正整數 xx,表示答案。

樣例輸入:

6
1 2 2 1 2 1

樣例輸出:

5

樣例說明:

選擇區間爲[2,4][2,4],翻轉後的序列爲(1,1,2,2,2,1)(1,1,2,2,2,1),最長不下降子序列爲 a1,a2,a3,a4,a5a_1,a_2,a_3,a_4,a_5, 長度爲 55

數據範圍:

對於 10%10\%的數據,1n101≤n≤10

對於 40%40\%的數據,1n2001≤n≤200

對於 70%70\%的數據,1n20001≤n≤2000

對於 100%100\%的數據,1n1000001≤n≤100000

題解

如果不能翻轉的話,求的就是最長的一段11加上一段22;如果能翻轉的話,一段11,一段22,一段11也可以成爲答案;一段11,一段22,一段11,一段22同理,我們維護一下這四種情況的最長長度即可。

代碼
#include <bits/stdc++.h>
using namespace std;
const int M=1e5+5;
int que[M],dp[M][4],n,ans;
void in(){scanf("%d",&n);}
void ac()
{
	for(int i=1;i<=n;i++)scanf("%d",que+i);
	for(int i=1;i<=n;i++)
	{
		dp[i][0]=dp[i-1][0]+(que[i]==1);
		dp[i][1]=max(dp[i-1][0],dp[i-1][1])+(que[i]==2);
		dp[i][2]=max(dp[i-1][1],dp[i-1][2])+(que[i]==1);
		dp[i][3]=max(dp[i-1][2],dp[i-1][3])+(que[i]==2);
		ans=max(max(dp[i][0],dp[i][1]),max(dp[i][2],dp[i][3]));
	}
	printf("%d\n",ans);
}
int main(){in(),ac();}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章