A dragon symbolizes wisdom, power and wealth. On Lunar New Year's Day, people model a dragon with bamboo strips and clothes, raise them with rods, and hold the rods high and low to resemble a flying dragon.
A performer holding the rod low is represented by a 1, while one holding it high is represented by a 2. Thus, the line of performers can be represented by a sequence a1, a2, ..., an.
Little Tommy is among them. He would like to choose an interval [l, r] (1 ≤ l ≤ r ≤ n), then reverse al, al + 1, ..., ar so that the length of the longest non-decreasing subsequence of the new sequence is maximum.
A non-decreasing subsequence is a sequence of indices p1, p2, ..., pk, such that p1 < p2 < ... < pk and ap1 ≤ ap2 ≤ ... ≤ apk. The length of the subsequence is k.
The first line contains an integer n (1 ≤ n ≤ 2000), denoting the length of the original sequence.
The second line contains n space-separated integers, describing the original sequence a1, a2, ..., an (1 ≤ ai ≤ 2, i = 1, 2, ..., n).
Print a single integer, which means the maximum possible length of the longest non-decreasing subsequence of the new sequence.
4 1 2 1 2
4
10 1 1 2 2 2 1 1 2 2 1
9
In the first example, after reversing [2, 3], the array will become [1, 1, 2, 2], where the length of the longest non-decreasing subsequence is 4.
In the second example, after reversing [3, 7], the array will become [1, 1, 1, 1, 2, 2, 2, 2, 2, 1], where the length of the longest non-decreasing subsequence is 9.
#include<bits/stdc++.h>
using namespace std;
const int MAX=3e3;
const int MOD=1e9+7;
typedef __int64 ll;
int a[MAX];
int suf[MAX][3],pre[MAX][3];//pre suf分别为以1或2结尾 开头 的最长子序列的长度
int num1[MAX][MAX];//记录区间[i,j]的1的个数
int num2[MAX][MAX];//记录区间[i,j]的2的个数
int d[MAX][MAX][2];//区间[i,j] 以1或2结尾的最长子序列的长度
int main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
memset(pre,0,sizeof pre);
memset(suf,0,sizeof suf);
for(int i=1;i<=n;i++)//以1或2结尾的最长子序列的长度
{
pre[i][1]=pre[i-1][1];
pre[i][2]=max(pre[i-1][1],pre[i-1][2]);
if(a[i]==1)pre[i][1]++;
else pre[i][2]++;
}
for(int i=n;i>=1;i--)//以1或2开头的最长子序列的长度
{
suf[i][2]=suf[i+1][2];
suf[i][1]=max(suf[i+1][1],suf[i+1][2]);
if(a[i]==1)suf[i][1]++;
else suf[i][2]++;
}
memset(num1,0,sizeof num1);
memset(num2,0,sizeof num2);
for(int i=1;i<=n;i++)//区间[i,j]以1或2结尾的最长子序列的长度
{
for(int j=i;j<=n;j++)
{
num1[i][j]=num1[i][j-1]+(a[j]==1);
num2[i][j]=num2[i][j-1]+(a[j]==2);
d[i][j][2]=max(d[i][j-1][1],d[i][j-1][2]);
d[i][j][1]=d[i][j-1][1];
if(a[j]==1)d[i][j][1]++;
else d[i][j][2]++;
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)//枚举翻转的区间并更新答案
{
ans=max(ans,pre[i-1][1]+num1[i][j]+suf[j+1][1]);
ans=max(ans,pre[i-1][1]+num1[i][j]+suf[j+1][2]);
ans=max(ans,pre[i-1][1]+num2[i][j]+suf[j+1][2]);
ans=max(ans,pre[i-1][2]+num2[i][j]+suf[j+1][2]);
ans=max(ans,pre[i-1][1]+j-i+1-d[i][j][2]+suf[j+1][2]);
ans=max(ans,pre[i-1][1]+j-i+1-d[i][j][1]+suf[j+1][1]);
}
}
cout<<ans<<endl;
return 0;
}