2013-06-04 08:32:52Morris

[UVA][math] 911 - Multinomial Coefficients

Problem G

Multinomial Coefficients

One of the first formulas we were taught in high school mathematics is MATH. Later on, we learned that this is a special case of the expansion $(a+b)^{n}$, in which the coefficient of $a^{k}b^{n-k}$ is the number of combinations of $n$ things taken $k$ at a time. We never learned (at least I never did...) what happens if instead of a binomial $a+b$ we have a multinomial $a+b+c+ldots +x$.

Problem

Your task is to write a program that, given a multinomial MATH, $kgeqslant 1$, computes the coefficient of a given term in the expansion of $m^{n}$, $ngeqslant 1$. The given term is specified by a sequence of $k$ integer numbers $z_{1}$, $z_{2}$, $ldots $, $z_{k}$, representing the powers of $a_{1}$, $a_{2}$, $ldots $, $a_{k}$ in the expansion. Note that MATH. For example, the coefficient of $ab^{2}c$ in $(a+b+c)^{4}$ is $12$.

Input

The input file contains several test cases, each of them with three lines. The first line contains a number representing the value of $n$. The second line contains a number representing the value of $k$. The third line contains $k$ numbers, representing the values of $z_{1}$, $z_{2}$, $ldots $,$z_{k}$. All test cases are such that $kleqslant 100$ and the computed coefficient is less than $2^{31}$.

Output

For each test case, write to the output one line. This line contains one integer number representing the value of the coefficient of the term MATH in the expansion of MATH.

Sample Input 1

4
3
1 2 1

Sample Output 1

12

Sample Input 2

7
4
2 3 0 2

Sample Output 2

210

Pedro Guerreiro, MIUP'2003
(Portuguese National ACM Programming Contest)

不能使用 N! / (x1!x2!...xn!), x1+x2+x3+ ... + xn = n
用陣列表示,然後慢慢消去。

#include <stdio.h>

int gcd(int x, int y) {
    int t;
    while(x%y)
        t = x, x = y, y = t%y;
    return y;
}
int main() {
    int i, j, k;
    int n, m, x;
    while(scanf("%d %d", &n, &m) == 2) {
        int A[105], sum = 0;
        for(i = 1; i <= n; i++)
            A[i] = i;
        while(m--) {
            scanf("%d", &x);
            sum += x;
            for(i = 2; i <= x; i++) {
                j = i;
                for(k = 2; k <= n; k++) {
                    int g = gcd(A[k], j);
                    A[k] /= g;
                    j /= g;
                }
            }
        }
        long long ret = 1;
        if(sum != n) {ret = 0;}
        else {
            for(i = 1; i <= n; i++)
                ret *= A[i];
        }
        printf("%lld\n", ret);
    }
    return 0;
}