Table CodeForces - 232B (144 div1 B) (dp + fast power)

Links: http://codeforces.com/problemset/problem/232/B

Implication: Give a large matrix of n*m (m >= n), put a point in the matrix to satisfy the number of k points for each small matrix of n*n.

Ideas for problem solving:


For a matrix S1 A of n*n is the number of points i n the left column, B is the number of points i n the right column of S2, so there is A+T=B+T. So when the number of points i n column I of the first n*n matrix is determined, n+i, n+2*i... The number of points will be determined, so the problem is transformed into finding the number of points i n each column of the first n * n matrix. When dp[i][j] is the number of J points i n column i, it is not difficult to deduce that dp[i][j]= min(n,j)x=0dp[i 1][j x] Cxn. It is described i n language that the number of J points i n column I is determined by column i-1 multiplying j-x points i n column n to select x points. Of course, Cxn here should take into account the following N + i, n + 2 * i... Point effect.
Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

#define LL long long
using namespace std;
const int MOD = 1e9 + 7;
const int Max = 120;
LL C[Max][Max];
LL Z[Max][Max];
LL dp[Max][15000];

void get_combinations() {//Recursion of Combination Number
    for (int a = 1; a <= 100; a++) {
        C[a][0] = C[a][a] = 1;
        for (int b = 1; b < a; b++) {
            C[a][b] = (C[a - 1][b - 1] + C[a - 1][b]) % MOD;//For a point, if it is determined to be C[a - 1][b - 1], it is determined not to be C[a - 1][b]
        }
    }
}

LL pow_MOD(LL n, LL m) {//Counting
    LL ans = 1;
    while (m) {
        if (m & 1)ans = (ans * n) % MOD;
        n = (n * n) % MOD;
        m >>= 1;
    }
    return ans;
}

int main() {
    LL n, m, k;
    get_combinations();
    scanf("%lld%lld%lld", &n, &m, &k);
    for (LL a = 1; a <= n; a++) {//Determining the number of b in column a will have an impact on the future
        for (LL b = 0; b <= n; b++) {//When the remaining number of m%n is still enough a, it will affect the latter m/n+1 column, otherwise it will affect the m/n column.
            Z[a][b] = pow_MOD(C[n][b], m / n +  + (m % n >= a));
        }
    }
    dp[0][0] = 1;
    for (LL a = 1; a <= n; a++) {//For line a, the state of b points is determined.
        for (LL b = 0; b <= min(k, n * a); b++) {
            for (LL c = 0; c <= min(b, n); c++) {
                dp[a][b] = (dp[a][b] + dp[a - 1][b - c] * Z[a][c]) % MOD;
            }
        }
    }
    printf("%lld\n", dp[n][k]);
    return 0;
}

Posted by Alphamonkey on Sat, 09 Feb 2019 20:15:17 -0800