码迷,mamicode.com
首页 > 其他好文 > 详细

Uva12034 (组合数取模)

时间:2018-08-22 00:11:48      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:printf   int   二维   style   a*   一个   code   rate   lucas定理   

题意:两匹马比赛有三种比赛结果,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 (组合数取模)

标签:printf   int   二维   style   a*   一个   code   rate   lucas定理   

原文地址:https://www.cnblogs.com/romaLzhih/p/9515151.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!