标签:cpp 答案 翻转 分组 最大值 isp printf == span
这题乍一看不好想,但是看到 \(1 \leq a_i \leq 2\) 时,便发现有玄机。
可得知最终答案是在 \([1,1,1,...][2,2,2,...][1,1,1,...][2,2,2,...]\) 这样的序列中,通过翻转第 \(2\),\(3\) 个序列之后得出。
我们可以用动态规划来维护每一段的最大值。
定义 \(f[i][j]\) 为前 \(i\) 个数中前 \(j\) 段的答案。
对于序列
\(111112222\)
可以将其按上面分成两组。
合理运用一下判等,
则有
对于序列
\(12212211212\)
得到最终答案时的最长不下降子序列是:
\(111122222\)
在此基础上翻转回去,则为:
\(122221112\)
发现它符合上面的按 \(4\) 个组的分组形式。
则有
观察,发现状态转移方程可以压掉第一维。
ll n,ans,f[12];
int main()
{
n=read();
for (ll i = 1; i <= n; i++)
{
ll tmp;
scanf("%lld", &tmp);
f[1] += (tmp == 1);
f[2] = max(f[1], f[2] + (tmp == 2));
f[3] = max(f[2], f[3] + (tmp == 1));
f[4] = max(f[3], f[4] + (tmp == 2));
}
printf("%lld\n",f[4]);
return 0;
}
标签:cpp 答案 翻转 分组 最大值 isp printf == span
原文地址:https://www.cnblogs.com/EdisonBa/p/14702135.html