Codeforces 932 E. Team Work(组合数学)

http://codeforces.com/contest/932/problem/E

题意:

  可以看做 有n种小球,每种小球有无限个,先从中选出x种,再在这x种小球中任选k个小球的方案数

选出的x种不一样,任选k个球的顺序不一样 均视做不同的方案

f[i][j] 表示选了i个小球,来自j种的方案数

那么答案就是

考虑选的第i个球是否是选过的一种,

f[i][j]=f[i-1][j]*j+f[i-1][j-1]*(n-(j-1))

#include<cstdio>
#include<algorithm>

using namespace std;

const int mod=1e9+7;

int f[5001][5001];

int Pow(int a,int b)
{
    int res=1;
    for(;b;a=1LL*a*a%mod,b>>=1)
        if(b&1) res=1LL*res*a%mod;
    return res;
}

int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    f[0][0]=1;
    for(int i=1;i<=k;++i) 
        for(int j=1;j<=i;++j)
            f[i][j]=(1LL*f[i-1][j]*j%mod+1LL*f[i-1][j-1]*(n-j+1)%mod)%mod;
    int ans=0;
    int m=min(n,k);
    for(int i=1;i<=m;++i) ans=(ans+1LL*f[k][i]*Pow(2,n-i)%mod)%mod;
    printf("%d",ans);
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8540851.html