【题意】
给n, n个数只有1,2组成, 翻转【L,R】后问最长不降序列长度;
【思路】
只有1,2组成,最长是1,2 那么 第一个2 出现的位置 P 【L,P】翻转使得后面的2的数目减少
【P,R】翻转使得 前面1 的数目增加
前面1的前缀和,后面2的后缀和,, 枚举p,然后 枚举 L,R 的位置, 使得 【1,L】 1的数目 + 【L,P】2的数目
【R,N】 2的数目 + 【P,R】 1的数目 之和 最大
【代码】
#include <iostream>
#include <bits/stdc++.h>
#include <stdio.h>
#define mem(a,b) memset(a,b,sizeof(a))
const int MAXN=1e5+5;
const int INF=0x3f3f3f3f;
#define SHUT ios_base::sync_with_stdio(false); cout.setf(ios::fixed); cout.precision(20); cout.tie(nullptr); cin.tie(nullptr);
using namespace std;
int a[MAXN];
int pre[MAXN];
int aft[MAXN];
int main()
{
SHUT;
int n;
cin>>n;
mem(a,0);
for(int i=1;i<=n;i++)
cin>>a[i];
mem(pre,0);
mem(aft,0);
for(int i=1,j=n;i<=n;i++,j--)
{
pre[i]=pre[i-1]+(a[i]==1);
aft[j]=aft[j+1]+(a[j]==2);
}
int ans=-INF;
for(int i=1;i<=n+1;i++)
{
int t1=0,t2=0;
for(int j=1;j<=i;j++) t1=max(t1,pre[j-1]+aft[j]-aft[i]);
for(int j=i;j<=n+1;j++) t2=max(t2,aft[j]+pre[j-1]-pre[i-1]);
ans=max(ans,t1+t2);
}
cout<<ans<<endl;
return 0;
}
123