HDU 6143 Killer Names

来源:互联网 发布:python 自带 IDLE 编辑:程序博客网 时间:2024/05/22 04:40

题意:每个人的名字由两部分组成,每部分的长度是n,给你m种字符,最多能构成多少个人的名字。
分析:就是一个组合数。如果n个长度用x个字符表达,那就相当于n个不同小球放在x个不同的盒子里。设其结果为f(x),那么f(x) = x ^ n - C(x, 1) * f(x - 1) - C(x, 2) * f(x - 2) …… - C(x, x - 1) * f(1).
然后就枚举两边各用了多少种字符统计结果。

#include<cstdio>#define mo 1000000007#include<iostream>using namespace std;typedef long long ll;ll n, m;ll C[2005][2005];ll mul[10000];ll cal[2005];ll quickM(ll a, ll b){    ll ans = 1;    while(b){        if(b & 1) ans = ans * a % mo;        b >>= 1;        a = a * a % mo;    }    return ans;}int main(){    mul[0] = 1;    for(ll i = 1; i <= 3000; i++) mul[i] = mul[i] * (i - 1) % mo;    C[0][0] = 1;    for(int i = 1; i <= 2001; i++){        C[i][0] = 1;        for(int j = 1; j <= i; j++){            C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mo;        }    }    int T;    scanf("%d", &T);    while(T--){        scanf("%lld%lld", &n, &m);        ll ans = 0;        for(ll i = 1; i <= n; i++){            cal[i] =  quickM(i, n);            for(int j = 1; j < i; j++){                cal[i] -= C[i][j] * cal[j] % mo;                cal[i] = (cal[i] + mo ) % mo;            }        }        for(ll i = 1; i <= n; i++){            if(i >= m) break;            for(ll j = 1; j <= n; j++){                if(j > m - i) break;                ans += C[m][i] * cal[i] % mo * cal[j] % mo * C[m - i][j] % mo;                ans %= mo;            }        }        printf("%lld\n", ans);    }    return 0;}
原创粉丝点击