(关键词-Input)

Description

在一串未打结的项链上(意思就是说项链的左端和右端不相连),有N颗珠子,你有M种颜色,然后就问你有多少种方法将每一颗珠子都染上颜色,使得任意两颗相邻的珠子的颜色不同。
Input

输入只有一行,三个正整数N、M和P,之间以一个空格隔开。
Output

输出只有一行,表示染色的方法总数模P。
Sample Input
5 4 13
Sample Output
12
HINT

样例一共有324种染色方法,对13取模后是12。

对于10%的数据,N=1,M<=10,P<=10;

对于20%的数据,N<=10,M<=10,P<=100;

对于50%的数据,N,M,P<=1,000,000,000;

对于100%的数据,1<=N,M,P<=1,000,000,000,000,000,000,且M>=2。

TLE代码贴一个,可以用stl,但是不能用vector

#include <iostream>
using namespace std;
long long dp[2]; 
long long ans(long long N, long long M, long long P) {
    dp[1] = M;
    for (int i = 2; i <= N; ++i) {
        dp[i % 2] = (dp[(i - 1) % 2] * (M - 1)) % P;
    }
    return dp[N % 2];
}

int main() {
    long long N, M, P;
    cin >> N >> M >> P;
    long long result = ans(N, M, P);
    cout << result;
    return 0;
}

单链表或者stl的list

【以下回答由 GPT 生成】

这是一个动态规划问题,我们可以使用动态规划来解决。

首先,我们定义一个二维数组dp,其中dp[i][j]表示染色i颗珠子并且最后一颗珠子的颜色为j的染色方法总数。初始时,我们将所有元素初始化为0。

接下来,我们考虑状态转移方程。对于染色第i颗珠子,有两种情况: 1. 如果第i颗珠子的颜色与第i-1颗珠子的颜色相同,那么第i颗珠子有M-1种颜色可以选择。此时,我们将第i颗珠子的颜色设置为j,那么第i-1颗珠子的颜色就不能是j。因此,第i颗珠子的染色方法总数为dp[i][j] = (dp[i][j] + dp[i-1][k]) % P,其中0 <= k < M且k != j。 2. 如果第i颗珠子的颜色与第i-1颗珠子的颜色不同,那么第i颗珠子有M种颜色可以选择。此时,我们将第i颗珠子的颜色设置为j,第i-1颗珠子的颜色可以是任意颜色。因此,第i颗珠子的染色方法总数为dp[i][j] = (dp[i][j] + dp[i-1][k]) % P,其中0 <= k < M。

最后,我们只需要计算出dp[N][j]的所有值,并将它们相加,即为染色的方法总数。

具体的实现代码如下:

def ans(N, M, P):
    dp = [[0] * M for _ in range(N+1)]
    dp[1] = [1] * M

    for i in range(2, N+1):
        for j in range(M):
            for k in range(M):
                if j != k:
                    dp[i][j] = (dp[i][j] + dp[i-1][k]) % P
                else:
                    dp[i][j] = (dp[i][j] + dp[i-1][k] * (M-1)) % P

    result = sum(dp[N]) % P
    return result

N, M, P = map(int, input().split())
result = ans(N, M, P)
print(result)

时间复杂度分析: 假设N为项链的长度,M为颜色的数量,P为模数。外层循环的次数是N,中间两层循环的次数是M,内层循环的次数也是M。所以总时间复杂度为O(N*M^2)。

该解法可以通过100%的数据。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^