UVA12034 Race

嘟嘟嘟

令dp[i]表示在n个人中,有 i 个人获得第一名的方案数,转移方程为dp[i] = C(i, n) * dp[n - i]。C(i, n)就是从n个人中选 i 个第一,那么剩下的n - i 个人必须都不是第一,所以就从dp[n - i]转移过来。

因为模数不是质数,所以O(n2)杨辉三角递推。然后O(n2)dp预处理,O(1)查询。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 #define enter puts("")
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxn = 1e3 + 5;
21 const int mod = 10056;
22 inline ll read()
23 {
24   ll ans = 0;
25   char ch = getchar(), las = ' ';
26   while(!isdigit(ch)) las = ch, ch = getchar();
27   while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
28   if(las == '-') ans = -ans;
29   return ans;
30 }
31 inline void write(ll x)
32 {
33   if(x < 0) putchar('-'), x = -x;
34   if(x >= 10) write(x / 10);
35   putchar(x % 10 + '0');
36 }
37 
38 int c[maxn][maxn], dp[maxn];
39 
40 int main()
41 {
42   c[0][0] = 1;
43   for(int i = 1; i < maxn; ++i)
44     {
45       c[i][0] = 1;
46       for(int j = 1; j < maxn; ++j)
47     c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
48     }
49   dp[0] = 1;
50   for(int i = 1; i < maxn; ++i)
51       for(int j = 1; j <= i; ++j)
52     dp[i] = (dp[i] + c[i][j] * dp[i - j] % mod) % mod;
53   int T = read();
54   for(int i = 1; i <= T; ++i)
55     {
56       int n = read();
57       printf("Case %d: %d
", i, dp[n]);
58     }
59   return 0;
60 }
View Code
原文地址:https://www.cnblogs.com/mrclr/p/9753053.html