zoukankan      html  css  js  c++  java
  • [2011山东ACM省赛] Binomial Coeffcients(求组合数)

    Binomial Coeffcients

    Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

    题目描写叙述

     

    输入

     

    输出

     

    演示样例输入

    3
    1 1
    10 2
    954 723

    演示样例输出

    1
    45
    3557658

    提示

     

    来源

    山东省第二届ACM大学生程序设计竞赛

    解题思路:

    这道题坑死我了。

    。本来非常easy的一道题。却怎么也做不正确。。

    就是求组合数。结果对10000003取模。一開始对c(m,n)是用公式直接求的。可是计算过程中涉及到取余,不能用下面代码写:

    int c(int m,int n)
    {
        int sum=1;
        for(int i=1;i<=n;i++)
        {
            sum=sum*(m--)/i;
            sum%=mod;
        }
        return sum;
    }


    这个代码是错误的。

    比方 C(9,3)对5取余  上面的代码 的计算过程是这种   sum=sum*9/1   sum=9  sum%5=4     4*8/2=16   16%5=1  1*7/3 =?这下问题出来了把。

    不能整除。这个计算过程中不能进行取模运算,可是直接算又越界。后来又想到求组合数分子分母进行约分以后再计算。測试数据对,可是可怜的超时。

    哎。。因此仅仅能用组合递推得来算,由于每递推到一个数,假设它大于mod,就取模,这种一个组合式是正确的,由于题意就这样说得。因此由递推得到的每个组合式都是正确的,并且不会越界。

    另外须要注意的是: c[0][0]=1 这个题少了这一句就WA

    代码:

    #include <iostream>
    #include <string.h>
    using namespace std;
    const int mod=10000003;
    const int N=1002;
    int c[N][N];
    
    void init()//递推打表
    {
        memset(c,0,sizeof(c));
        c[0][0]=c[1][0]=c[1][1]=1;
        for(int i=2;i<N;i++)
        {
            c[i][i]=c[i][0]=1;
            for(int j=0;j<i;j++)
            {
                c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;//不会越界
            }
        }
    }
    int main()
    {
        init();
        int k;cin>>k;
        int a,b;
        while(k--)
        {
            cin>>a>>b;
            cout<<c[a][b]<<endl;//直接输出
        }
    }
    


     

  • 相关阅读:
    古谚、评论与论断、名篇与名言
    重读《西游记》
    重读《西游记》
    命名之法 —— 时间、季节、地点
    命名之法 —— 时间、季节、地点
    文言的理解 —— 古时的称谓、别称、别名
    文言的理解 —— 古时的称谓、别称、别名
    Oracle GoldenGate for Oracle 11g to PostgreSQL 9.2.4 Configuration
    瀑布 敏捷 文档
    POJ 1325 ZOJ 1364 最小覆盖点集
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/7260404.html
Copyright © 2011-2022 走看看