经典的三色小球相邻小球颜色不同,摆成一排的方案数【】

题目描述: 有三种颜色的球, 每种球的数量分别是a, b, c, 问把这三种小球摆成一排, 相邻小球颜色不同的方案数是多少? (同一个颜色的小球之间没有区别! ps: 如果有区别最后的ans再分别乘以每个颜色的数量的阶乘就行了)

思路: dp, dp[i][j][k][l] 表示剩ijk个 最后一个是l颜色, 那么讨论一下最后的颜色的种类就直接转移就行了.

AC Code

typedef long long ll;
ll dp[22][22][22][4];
void solve() {
    int n, m, k;
    while (cin >> n >> m >> k) {
        memset(dp, 0, sizeof(dp));
        dp[n][m][k][3] = 1;
        for (int i = n; i >= 0; i--) {
            for (int j = m; j >= 0; j--) {
                for (int p = k; p >= 0; p--) {
                    for (int l = 0; l <= 3; l++) {
                        if (l == 3) {
                            if (i > 0) dp[i-1][j][p][0] += dp[i][j][p][l];
                            if (j > 0) dp[i][j-1][p][1] += dp[i][j][p][l];
                            if (p > 0) dp[i][j][p-1][2] += dp[i][j][p][l];
                        }
                        if (l == 0) {
                            if (j > 0) dp[i][j-1][p][1] += dp[i][j][p][l];
                            if (p > 0) dp[i][j][p-1][2] += dp[i][j][p][l];
                        }
                        if (l == 1) {
                            if (i > 0) dp[i-1][j][p][0] += dp[i][j][p][l];
                            if (p > 0) dp[i][j][p-1][2] += dp[i][j][p][l];
                        }
                        if (l == 2) {
                            if (i > 0) dp[i-1][j][p][0] += dp[i][j][p][l];
                            if (j > 0) dp[i][j-1][p][1] += dp[i][j][p][l];
                        }
                    }
                }
            }
        }
        ll sum = 0;
        for (int l = 0; l <= 3; l++) {
            sum += dp[0][0][0][l];
        }
        cout << sum << endl;
    }
}

你可能感兴趣的:(dp思维)