暫無鏈接
單調序列
GISPZJZ 有一個長度爲 的序列。序列的所有元素都是 或者。
我們稱一序列是該序列的不下降子序列,滿足 ,且 。
現在 GISPZJZ 可以選擇序列中的一段區間,然後將整段反轉,例如挑選區間, 可以將序列變換爲。在此基礎上,GISPZJZ 希望在反轉 後,序列的最長不下降子序列最長。當然,GISPZJZ 也可以選擇不反轉任何區間。現在要求求出最優情況下,序列的最長不下降子序列的長度。
輸入:
第一行一個正整數 。
第二行 個數,分別爲 ,滿足 。
輸出:
一行一個正整數 ,表示答案。
樣例輸入:
6
1 2 2 1 2 1
樣例輸出:
5
樣例說明:
選擇區間爲,翻轉後的序列爲,最長不下降子序列爲 , 長度爲 。
數據範圍:
對於 的數據,。
對於 的數據,。
對於 的數據,。
對於 的數據,。
題解
如果不能翻轉的話,求的就是最長的一段加上一段;如果能翻轉的話,一段,一段,一段也可以成爲答案;一段,一段,一段,一段同理,我們維護一下這四種情況的最長長度即可。
代碼
#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();}