习题:A Twisty Movement (DP)

Posted loney-s

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题:A Twisty Movement (DP)相关的知识,希望对你有一定的参考价值。

题目

传送门

思路

注意题目中的最后一段话

这意味这选出的序列可以不是连续的

之后我们考虑最后的答案长什么样子

因为只能反转一次

所以最后的答案一定是由4个部分组成

[1111(cdots)] [222(cdots)] [111(cdots) ] [222(cdots) ]

如果没有可以看成空序列

之后就直接暴力DP搞就行了

(dp_{i,j})表示前(i)个数,前(j)个部分的最大值

(egin{cases}dp_{i,1}=dp_{i-1,1}+(a_i==1)\dp_{i,2}=max(dp_{i,1},dp_{i-1,2}+(a_i==2)\dp_{i,3}=max(dp_{i,2},dp_{i-1,3}+(a_i==1)\dp_{i,4}=max(dp_{i,3},dp_{i-1,4}+(a_i==2)end{cases})

很明显第一维是可以省略的

然而空间本来就够,所以省不省都无所谓了

代码

#include<iostream>
using namespace std;
int n;
int a[2005];
int dp[2005][5];
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        dp[i][1]=dp[i-1][1]+(a[i]==1);
        dp[i][2]=max(dp[i][1],dp[i-1][2]+(a[i]==2));
        dp[i][3]=max(dp[i][2],dp[i-1][3]+(a[i]==1));
        dp[i][4]=max(dp[i][3],dp[i-1][4]+(a[i]==2));
    }
    cout<<dp[n][4];
    return 0;
}

以上是关于习题:A Twisty Movement (DP)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 934C - A Twisty Movement

Codeforces-462C. A Twisty Movement

E - A Twisty Movement

[Codeforces 933A]A Twisty Movement

Codeforces Round #462 (Div. 1) A A Twisty Movement

dp的练习题;