AcWing - 337 - Combinatorial Mathematics poker = dp +

https://www.acwing.com/problem/content/description/339/

A feeling of something very sand sculpture.

First, when the state Yaoan set number of sheets to set up, so the space complexity is relatively small. Because the suit and face value in itself and there is no relationship.

Then when pretreated directly consider the impact of color, is multiplied by a number of permutations.

Remember to look at the inclusion-exclusion, or the answer is very problematic.

I do not know why not take the unsigned long long (the reason is because the subtraction a-1> = 0 overflow), and had put forward a __int128 to represent modulus, really troublesome.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 ull;

ull dp[20][20][20][20] = {};
ull TWO = 2, THREE = 3, FOUR = 4, SIX = 6, MOD = 1;

const ull CEIL = 13;
string s;

ull mut(ull a, ull b) {
    ull res = 0;
    while(b) {
        if(b & 1)
            res = (res + a) % MOD;
        a = (a + a) % MOD;
        b >>= 1;
    }
    return res;
}

void init() {
    MOD <<= 64;
    for(ull d = 0; d <= CEIL; ++d) {
        for(ull c = 0; c <= CEIL; ++c) {
            for(ull b = 0; b <= CEIL; ++b) {
                for(ull a = 0; a <= CEIL; ++a) {
                    if(a == 0 && b == 0 && c == 0 && d == 0) {
                        dp[0][0][0][0] = 1llu;
                        continue;
                    }
                    if(a - 1 >= 0)
                        dp[a][b][c][d] += mut(dp[a - 1][b][c][d], a);
                    if(b - 1 >= 0) {
                        dp[a][b][c][d] += mut(mut(dp[a + 1][b - 1][c][d], TWO), b);
                        dp[a][b][c][d] -=  mut(mut(dp[a][b - 1][c][d], TWO), b);
                    }
                    if(c - 1 >= 0) {
                        dp[a][b][c][d] += mut(mut(dp[a][b + 1][c - 1][d], THREE), c);
                        dp[a][b][c][d] -= mut(mut(mut(dp[a + 1][b][c - 1][d], THREE), TWO), c);
                        dp[a][b][c][d] += mut(mut(mut(dp[a][b][c - 1][d], THREE), TWO), c);
                    }
                    if(d - 1 >= 0) {
                        dp[a][b][c][d] += mut(mut(dp[a][b][c + 1][d - 1], FOUR), d);
                        dp[a][b][c][d] -= mut(mut(mut(dp[a][b + 1][c][d - 1], FOUR), THREE), d);
                        dp[a][b][c][d] += mut(mut(mut(mut(dp[a + 1][b][c][d - 1], FOUR), THREE), TWO), d);
                        dp[a][b][c][d] -= mut(mut(mut(mut(dp[a][b][c][d - 1], FOUR), THREE), TWO), d);
                    }
                    dp[a][b][c][d] = (dp[a][b][c][d] % MOD + MOD) % MOD;
                }
            }
        }
    }

}

void write(ull ans) {
    if(ans >= 10) {
        write(ans / 10);
    }
    putchar(ans % 10 + '0');
}

int cnt[14] = {};
int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku

    init();
    int t;
    cin >> t;
    for(int ti = 1; ti <= t; ++ti) {
        int n;
        cin >> n;
        memset(cnt, 0, sizeof(cnt));
        for(int i = 1; i <= n; ++i) {
            cin >> s;
            if(s[0] == 'T') {
                cnt[10]++;
            } else if(s[0] == 'A') {
                cnt[1]++;
            } else if(s[0] == 'J') {
                cnt[11]++;
            } else if(s[0] == 'Q') {
                cnt[12]++;
            } else if(s[0] == 'K') {
                cnt[13]++;
            } else {
                cnt[s[0] - '0']++;
            }
        }
        ull cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0;
        for(int i = 1; i <= 13; ++i) {
            if(cnt[i] == 1)
                cnt1++;
            else if(cnt[i] == 2)
                cnt2++;
            else if(cnt[i] == 3)
                cnt3++;
            else if(cnt[i] == 4)
                cnt4++;
        }
        ull tmp = dp[cnt1][cnt2][cnt3][cnt4];
        cout << "Case #" << ti << ": ";
        write(tmp);
        cout << "\n";
    }
}

So it confirms the sentence, nothing on the need to use unsigned, otherwise an accident.

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

ull dp[20][20][20][20] = {};

ull TWO = 2, THREE = 3, FOUR = 4, SIX = 6;

const int CEIL = 13;
string s;

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    for(int d = 0; d <= CEIL; ++d) {
        for(int c = 0; c <= CEIL; ++c) {
            for(int b = 0; b <= CEIL; ++b) {
                for(int a = 0; a <= CEIL; ++a) {
                    if(a == 0 && b == 0 && c == 0 && d == 0) {
                        dp[0][0][0][0] = 1llu;
                        continue;
                    }
                    if(a - 1 >= 0)
                        dp[a][b][c][d] += dp[a - 1][b][c][d] * a;
                    if(b - 1 >= 0) {
                        dp[a][b][c][d] += dp[a + 1][b - 1][c][d] * TWO * b;
                        dp[a][b][c][d] -= dp[a][b - 1][c][d] * TWO * b;
                    }
                    if(c - 1 >= 0) {
                        dp[a][b][c][d] += dp[a][b + 1][c - 1][d] * THREE * c;
                        dp[a][b][c][d] -= dp[a + 1][b][c - 1][d] * THREE * TWO * c;
                        dp[a][b][c][d] += dp[a][b][c - 1][d] * THREE * TWO * c;
                    }
                    if(d - 1 >= 0) {
                        dp[a][b][c][d] += dp[a][b][c + 1][d - 1] * FOUR * d;
                        dp[a][b][c][d] -= dp[a][b + 1][c][d - 1] * FOUR * THREE * d;
                        dp[a][b][c][d] += dp[a + 1][b][c][d - 1] * FOUR * THREE * TWO * d;
                        dp[a][b][c][d] -= dp[a][b][c][d - 1] * FOUR * THREE * TWO * d;
                    }
                }
            }
        }
    }
    int t;
    scanf("%d", &t);
    for(int ti = 1; ti <= t; ++ti) {
        int n;
        scanf("%d", &n);

        int cnt[14] = {};
        for(int i = 1; i <= n; ++i) {
            cin >> s;
            if(s[0] == 'T') {
                cnt[10]++;
            } else if(s[0] == 'A') {
                cnt[1]++;
            } else if(s[0] == 'J') {
                cnt[11]++;
            } else if(s[0] == 'Q') {
                cnt[12]++;
            } else if(s[0] == 'K') {
                cnt[13]++;
            } else {
                cnt[s[0] - '0']++;
            }
        }
        ull cnt1 = 0, cnt2 = 0, cnt3 = 0, cnt4 = 0;
        for(int i = 1; i <= 13; ++i) {
            if(cnt[i] == 1)
                cnt1++;
            else if(cnt[i] == 2)
                cnt2++;
            else if(cnt[i] == 3)
                cnt3++;
            else if(cnt[i] == 4)
                cnt4++;
        }
        ull tmp = dp[cnt1][cnt2][cnt3][cnt4];
        printf("Case #%d: %llu\n", ti, tmp);
    }
}

Guess you like

Origin www.cnblogs.com/Inko/p/11605459.html