codeforces 1140E Palindrome-less Arrays

Posted opooopooo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 1140E Palindrome-less Arrays相关的知识,希望对你有一定的参考价值。

题目链接:http://codeforces.com/contest/1140/problem/E

 

题目大意:

如果一个数组的存在一个奇数长的回文就不好。

不是不好的数组是好的。

你可以把-1用1到k中一个数替换。问可以有多少种不同的好数组。

 

开虚拟赛最后一分钟把它A了,很开心,很开心。

 

思路:

我们翻译一下,如果存在长度为5的回文就必须会出现长度为3的回文。

也就是说不能出现长度为3回文。

也就是说x[i]!=x[i+2],x[i]!=x[i-2];(x[i]为输入数组)

 

那我们把数组分为两个数组,按奇偶分。(1,3,5,,,)(2,4,6,,,)

 

这两个数组就都要满足一个条件x[i]!=x[1+i]&&x[i]!=x[i-1];(相邻两个数不能相等)

 

然后我们就开始DP啦。

 

对于奇偶两个数组我就分析一个啦,因为都差不多。(相邻两个数不能相等)

 

首先,当然是n*k的DP。

DP[a][b]表示到a下为b的方案数。

所以DP[a][b]等于所有DP[a-1][i](1<=i<=k,i!=b)的和。

如果x[a]为-1,就算所有的1到k。

如果x[a]>0,就只算DP[a][x[a]];

 

这个可以理解吗?

 

可以理解就太好了!!!

 

然而,你在DP的过程中,发现DP[a][i](1<=i<=k)中只可能有两个不同的值(不会超过3个),而且产生不同的值是一个特殊的位置。

你可以先拿小一点的数据打表看看。

 

也就是说,对于每一个状态。只有两种可能,而不是k种可能。

所以,我们就可以写O(n)的DP了。

 

我画了两张图给你们看看。

技术图片

技术图片

 

 

然后到了愉快的贴代码时间了。不是很懂可以私聊QQ:1328247116,也可以下面留言。~~

 

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define ios ios::sync_with_stdio(false);
#define endl "\\n"
#define MAX 200050
#define mod 998244353

///
int x[MAX];
int dp[MAX];
int dp_1=1,dp_1_sum=1;
int dp_2=1,dp_2_sum=1;
int ans[MAX];
///
signed main()
{
    IOS;

    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>x[i];
    }

    if(x[1]>0){
        dp[1]=0;
        dp_1=x[1],dp_1_sum=1;
    }
    else{
        dp[1]=1;
        dp_1=1,dp_1_sum=1;
    }

    for(int i=3;i<=n;i+=2){
        if(x[i]>0){
            if(x[i]==dp_1){
                dp_1_sum=(m-1)*dp[i-2]%mod;
            }
            else{
                dp_1_sum=((m-2)*dp[i-2]%mod+dp_1_sum)%mod;
            }
            dp_1=x[i];
        }
        else{
            dp[i]=((m-2)*dp[i-2]%mod+dp_1_sum)%mod;
            dp_1_sum=(m-1)*dp[i-2]%mod;
        }
    }

    ///
    if(x[2]>0){
        dp[2]=0;
        dp_2=x[2],dp_2_sum=1;
    }
    else{
        dp[2]=1;
        dp_2=1,dp_2_sum=1;
    }

    for(int i=4;i<=n;i+=2){
        if(x[i]>0){
            if(x[i]==dp_2){
                dp_2_sum=(m-1)*dp[i-2]%mod;
            }
            else{
                dp_2_sum=((m-2)*dp[i-2]%mod+dp_2_sum)%mod;
            }
            dp_2=x[i];
        }
        else{
            dp[i]=((m-2)*dp[i-2]%mod+dp_2_sum)%mod;
            dp_2_sum=(m-1)*dp[i-2]%mod;
        }
    }
    int ans;
    if(n%2==0){
        ans=(dp_1_sum+(m-1)*dp[n-1]%mod)*(dp_2_sum+(m-1)*dp[n]%mod)%mod;
    }
    else{
        ans=(dp_1_sum+(m-1)*dp[n]%mod)*(dp_2_sum+(m-1)*dp[n-1]%mod)%mod;
    }
    cout<<ans;
    return 0;
}

/*


*/

 

以上是关于codeforces 1140E Palindrome-less Arrays的主要内容,如果未能解决你的问题,请参考以下文章

CF1140E Palindrome-less Arrays

CF1140E Palindrome-less Arrays(巧妙的递推)

CF1140E Palindrome-less Arrays(巧妙的递推)

编程小练习--回文数链长

codeforces上怎么看测试数据

如何看codeforces做了多少题