AtCoder Beginner Contest 307「E dp」

E - Distinct Adjacent

题目描述:

给两个数n和m,求一个长度为n的排列的数量,排列要满足如下条件:

  • a[i] >= 0 && a[i] <= m,即a[i]可以是0到m-1中任意的一个数
  • 任意相邻数字不能相等,同时a[1]不能等于a[n]

答案对998244353取模

思路:

假设没有a[1]!=a[n]的条件,那答案就是m*(m-1)n-1

有了这个限制条件以后,我们可以用dp来解决

dp[i][0]表示第i个数和第一个数字不相同时,前i个数字中任意相邻的两个数字不相同的方案数

dp[i][1]表示第i个数和第一个数字相同时,前i个数字中任意相邻的两个数字不相同的方案数

则状态转移为:

dp[i][0]=dp[i-1][0]*(m-2)+dp[i-1][1]*(m-1)

dp[i][1]=dp[i-1][0]

#include
#include
#include
#include

typedef long long ll;
ll mod = 998244353;
#define MAX 1000050
ll n, m, k, x, y, z;
ll dp[MAX][2];

int main(){
    scanf("%lld%lld", &n, &m);
    dp[1][0] = 0;dp[1][1] = m;
    for(int i = 2; i <= n; ++i){
        dp[i][0] = (dp[i-1][0] * (m-2) % mod + dp[i-1][1] * (m-1) % mod)%mod;
        dp[i][1] = dp[i-1][0];
    }
    printf("%lld\n", dp[n][0]);
    return 0;
}

你可能感兴趣的:(算法,动态规划)