nyoj 1328 派队方案

n场比赛划分成m个队伍,每个比赛只用一个队,没有空的集合。也就是说把包含n个元素的集合划分为正好m个非空子集的方法的数目,再乘m的全排列。


第二类Stirling数是把包含n个元素的集合划分为正好k个非空子集的方法的数目。   

递推公式为:   S(n,k)=0; (n
S(n,k) = S(n-1,k-1) + kS(n-1,k).
考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的
不可辨别的集合,方法数为S(p-1,k-1);
也可以前p-1种物品构成k个非空的不可辨别的集合,

第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

#include
using namespace std;
#define MOD 1000000007
long long f[105][105];
long long dp[105];

int main(){
	f[1][1]=f[2][2]=f[2][1]=1;
	
	for(int i=3;i<105;i++)
	for(int j=1;j<=i;j++)
	f[i][j]=(f[i-1][j-1]+j*f[i-1][j])%MOD;
	
	dp[0]=1;
	for(int i=1;i<105;i++)
	dp[i]=dp[i-1]*i%MOD;
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF){
	
		printf("%d\n",f[n][m]*dp[m]%MOD);
		
	}
	return 0;
}

你可能感兴趣的:(dp)