1. 程式人生 > >新疆大學(新大)OJ xju 1006: 比賽排名 第二類斯特林數+階乘

新疆大學(新大)OJ xju 1006: 比賽排名 第二類斯特林數+階乘

bds 思路 jpg stat cin idt line main enter

題目鏈接:http://139.129.36.234/JudgeOnline/problem.php?id=1006

第二類斯特林數:

第二類Stirling數實際上是集合的一個拆分,表示將n個不同的元素拆分成m個集合的方案數,記為 技術分享 或者技術分享

第二類Stirling數的推導和第一類Stirling數類似,可以從定義出發考慮第n+1個元素的情況,假設要把n+1個元素分成m個集合則分析如下: (1)如果n個元素構成了m-1個集合,那麽第n+1個元素單獨構成一個集合。方案數技術分享 。 (2)如果n個元素已經構成了m個集合,將第n+1個元素插入到任意一個集合。方案數 m*S(n,m) 。   綜合兩種情況得:     技術分享

遞推式:dp[i][j] = dp[i-1][j-1]+j*dp[i-1][j]; 思路: 這題就是求斯特林數,即將n個隊伍分成i個集合(1 <= i <= n)。 然後對每個集合排序,乘上A(i,i)。也就是i !(i的階乘)。 代碼:
#include<cstdio>  
#include<cstring>
#include<iostream>
using namespace std;

const int mod = 10056;

int dp[1010][1010];
int main()  {  
  
int t,n; cin >> t; int k = 1; while(t--){ cin >> n; dp[0][0] = 1; for(int i = 1;i <= n; i++){ for(int j = 1;j <= i; j++){ dp[i][j] = (dp[i-1][j-1]+j*dp[i-1][j])%mod; } } int num = 1;
int ans = 0; for(int j = 1;j <= n; j++){ num = (num * j)%mod; ans = (ans + num*dp[n][j])%mod; } cout << "Case " << k++ << ": "; cout << ans << endl; } return 0; }

新疆大學(新大)OJ xju 1006: 比賽排名 第二類斯特林數+階乘