1. 程式人生 > >Uva12034 (組合數取模)

Uva12034 (組合數取模)

傳遞 組合數取模 組合 並且 gen mod 總數 比賽結果 對組

題意:兩匹馬比賽有三種比賽結果,n匹馬比賽的所有可能結果總數

解法:

設答案是f[n],則假設第一名有i個人,有C(n,i)種可能,接下來還有f(n-i)種可能性,因此答案為 ΣC(n,i)f(n-i)

另外這裏給出兩個求組合數的模板,盧卡斯定理的p是模數,並且要求是素數,第二個是遞推式,適合於n<2000的情況

 1 #include<cstdio>
 2 using namespace std;
 3 const int maxn = 1e3;
 4 const int mod = 10056;
 5 typedef long long ll;
 6 
 7 /*--------------------------盧卡斯定理取模-----------------------
*/ 8 ll exp_mod(ll a, ll b, ll p) { 9 ll res = 1; 10 while (b != 0) { 11 if (b & 1) res = (res * a) % p; 12 a = (a*a) % p; 13 b >>= 1; 14 } 15 return res; 16 } 17 18 ll Comb(ll a, ll b, ll p) { 19 if (a < b) return 0; 20 if (a == b) return
1; 21 if (b > a - b) b = a - b; 22 23 ll ans = 1, ca = 1, cb = 1; 24 for (ll i = 0; i < b; ++i) { 25 ca = (ca * (a - i)) % p; 26 cb = (cb * (b - i)) % p; 27 } 28 ans = (ca*exp_mod(cb, p - 2, p)) % p; 29 return ans; 30 } 31 //Lucas定理對組合數取模 32 ll Lucas(int
n, int m, int p) { 33 ll ans = 1; 34 while (n&&m&&ans) { 35 ans = (ans*Comb(n%p, m%p, p)) % p; 36 n /= p; 37 m /= p; 38 } 39 return ans; 40 } 41 42 /*----------------------組合數遞推公式(適用n<2000)---------------------------*/ 43 int C[maxn+10][maxn+10]; 44 void Cal_C(int n) { 45 //傳遞的是一個二維的數組c 46 for (int i = 0; i <= n; i++){ 47 C[i][0] = C[i][i] = 1; 48 for (int j = 1; j < i; j++) 49 C[i][j] = (C[i - 1][j - 1]%mod + C[i - 1][j]%mod)%mod; 50 } 51 return; 52 } 53 /*--------------------------------------------------------------------------*/ 54 55 int f[maxn+11]; 56 void generate() { 57 Cal_C(maxn); 58 f[0] = 1; 59 for (int i = 1; i <= maxn; i++) { 60 f[i] = 0; 61 for (int j = 1; j <= i; j++) 62 f[i] = (f[i] + C[i][j] * f[i - j]) % mod; 63 } 64 return; 65 } 66 67 int main() { 68 int T; scanf("%d", &T); 69 int kase = 1; 70 generate(); 71 while (T--) { 72 int n; scanf("%d", &n); 73 printf("Case %d: %d\n", kase++, f[n]); 74 } 75 return 0; 76 }

Uva12034 (組合數取模)