• Uva12034 (组合数取模)


    题意:两匹马比赛有三种比赛结果,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
    ", kase++, f[n]);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    [转]VC++中操作XML(MFC、SDK)
    VC解析XML--使用CMarkup类解析XML
    C++基础--完善Socket C/S ,实现客户端,服务器端断开重连
    socket编程的select模型
    libevent源码分析
    socket异步编程--libevent的使用
    Win32编程点滴3
    Win32编程点滴5
    thrift之TTransport层的堵塞的套接字I/O传输类TSocket
    Thrift之代码生成器Compiler原理及源码详细解析1
  • 原文地址:https://www.cnblogs.com/romaLzhih/p/9515151.html
Copyright © 2020-2023  润新知