Uva 10943 - How do you add ?( 组合数公式 + 递推 )

 

 

Uva 10943 - How do you add ?( 组合数公式 + 递推 )

 

 

题意:
给定一个数N,分解韡k个数,问有多少种组合.数可以重复 (N<=100)


分析:
通过组合数学将题目抽象为 N个相同的小球,放入k个不同的盒子中,且允许盒子为空
然后就可以用隔板法
------> ANS = C(N+M-1,M-1)
隔板法--> BD
隔板法

N个相同的物品需要放入k个盒子中

如果盒子不能为空

那么公式应该为C(N-1,K-1)

如果盒子可以为空,那么可以加入K个物品,并对这些物品按照上面的公式进行分类,最后每一堆都减去1

那么公式为C(N+K-1,K-1)

 


然后再根据组合数的性质可以进行递推(这题数据范围比较小)
----> C(A,B) = C(A-1,B) + C(A-1,B-1);
//组合数性质

C(n,m) = C(n,n-m)

//递推性质\

C(n,m) = C(n-1,m) + C(n-1,m-1)

 


预处理一遍之后即可相应
#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

#define MAXN 201

#define MOD 1000000

#define CLR( a, b )     memset( a, b, sizeof(a) )



int C[MAXN][MAXN];



void init()

{

    CLR(C,0);

    for(int i=0;i<MAXN;i++)

        C[i][0] = 1;

    for(int i=1;i<MAXN;i++)

        for(int j=1;j<=i;j++)

            C[i][j] = ( C[i-1][j] + C[i-1][j-1] ) % MOD;    //组合数性质

}



void Orz()

{

    init();

    int n, m;

    while(~scanf("%d %d",&n,&m) && (n+m))

    {

        printf("%d\n",C[n+m-1][m-1]);       //隔板法

    }

}



int main()

{

    Orz();

    return 0;

}
代码君

 

你可能感兴趣的:(uva)