hdu 4045 第二类Stirling数

来源:互联网 发布:淘宝微博运营团队 编辑:程序博客网 时间:2024/03/29 03:36

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4045

大意:序号为1到n,选r个东西,序列之差大于等于k,放到m个盒子里。

分为两部分:

1.C(n-((r-1)*k+r+1),r)。。。。插板法。。。实在不想看高中的东西了

2.就是第二类斯特林数了

S(n+1,k)=S(n-1,k-1) + kS(n-1,k)

#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll mod= 1000000007;const int maxn=1005;ll stir2[maxn][maxn];void get_stir2(){    for(int i=1;i<maxn;i++){        stir2[i][0]=0;        stir2[i][i]=1;        for(int j=1;j<i;j++)            stir2[i][j]=(stir2[i-1][j-1]+j*stir2[i-1][j])%mod;    }}void gcd(ll a,ll b,ll &d,ll &x,ll &y){    if(!b){d=a;x=1;y=0;}    else{ gcd(b,a%b,d,y,x);y-=x*(a/b);}}ll inv(ll a,ll n){    ll d,x,y;    gcd(a,n,d,x,y);    return d==1? (x+n)%n:-1;}ll C(ll n,ll m){  //C(n,m)£¬mÀïÑ¡n¸ö¡£    ll ans,a=1,b=1;    for(ll i=m;i>=m-n+1;i--)        a=a*i%mod;    for(ll i=n;i>1;i--)        b=b*i%mod;    ans=a*inv(b,mod)%mod;    return ans;}int main(){    get_stir2();    ll n,r,k,m;    while(~scanf("%lld%lld%lld%lld",&n,&r,&k,&m)){        ll tmp=n-((r-1)*k+1);        if (tmp<0){            printf("0\n");            continue;        }        ll sum=0,ans=C(r,tmp+r);        for(int i=1;i<=m;i++)            sum=(sum+stir2[r][i])%mod;        ans=(ans*sum)%mod;        printf("%lld\n",ans);    }    return 0;}


原创粉丝点击