CodeForces 933A A Twisty Movement 题解

题目传送门

题目大意: 给出一个 12 12 序列,允许你进行一次区间翻转,问最长不下降子序列长度。

题解

显然最后的答案是一段1序列+一段2序列+一段1序列+一段2序列,只需要把第二段和第三段所在的区间翻转即可。

那么考虑 d p dp ,设 f [ i ] [ j ] f[i][j] 表示前 i i 个数中前 j j 段的最大值,其中 j [ 1 , 4 ] j\in[1,4]

那么显然转移的时候可以贪心地转移,比如 f [ i ] [ 2 ] = max ( f [ i 1 ] [ 2 ] + [ i = = 2 ] , f [ i ] [ 1 ] ) f[i][2]=\max(f[i-1][2]+[i==2],f[i][1]) ,因为这个东西是没有后效性的,所以贪心地取最大就好了。

代码:

#include <cstdio>
#include <cstring>

int n,f[5];//第一维可以滚掉,所以没必要用
inline int max(int x,int y){return x>y?x:y;}

int main()
{
	scanf("%d",&n);
	for(int i=1,x;i<=n;i++)
	{
		scanf("%d",&x);
		f[1]+=(x==1);
		f[2]=max(f[1],f[2]+(x==2));
		f[3]=max(f[2],f[3]+(x==1));
		f[4]=max(f[3],f[4]+(x==2));
	}
	printf("%d",f[4]);
}
发布了234 篇原创文章 · 获赞 100 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/a_forever_dream/article/details/102972970