这题又开阔了我的眼界
不考虑翻转这个条件,a[i]只有1和2时,就很是快乐
最长不下降子序列肯定长这样
(11……22……)
我们处理一下,把1和2放在两组中
([11……][22……])
定义 (f[i][j]) (j为1或2)为前i个点,第i个点属于第j组
[f[i][1]=f[i-1][j]+(a[i]==1)
]
[f[i][2]=max(f[i-1][1],f[i-1][2]+(a[i]==2))
]
考虑一下翻转,比如
(1112212211212222)
它翻转后的最长不下降子序列是
(11111122222222)
(翻转区间 (4、12))
要是我们翻转回来,这个序列就变成了
(11122221112222)
发现它可以分为4组
([111][2222][111][2222]) (毕竟这样的话交换23区间就变成了上面的情况了)
所以就可以列出方程
[f[i][1]=f[i-1][1]+(a[i]==1)
]
[f[i][2]=max(f[i-1][1],f[i-1][2]+(a[i]==2)
]
[f[i][3]=max(f[i-1][2],f[i-1][3]+(a[i]==1)
]
[f[i][4]=max(f[i-1][3],f[i-1][4]+(a[i]==2)
]
然后我们压掉第一维就可
提供一个理解思路(以 (f[i][2]) 为例)
1.从 (f[i-1][1]) 转移:开启一个新的组
2.从 (f[i-][2]) 转移:往已经开启的组添加一个数
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
ll n,m,f[10],ans;
int main(){
scanf("%lld",&n);
for(ll i=1;i<=n;i++){
ll a1;
scanf("%lld",&a1);
f[1]+=(a1==1);
f[2]=max(f[1],f[2]+(a1==2));
f[3]=max(f[2],f[3]+(a1==1));
f[4]=max(f[3],f[4]+(a1==2));
}
cout<<f[4];
}