POJ 1942 Paths on a Grid(求组合数)

来源:互联网 发布:淘宝店铺装修托管 编辑:程序博客网 时间:2024/05/13 17:06

POJ 1942 Paths on a Grid

题目大意

给定n,m(n,m232)Cnn+m

分析

裸的求组合数的题

原公式是:

Cmn=AmnAmm=n!m!(nm)!=n(n1)...(nm+1)m!=n(n1)...(m+1)(nm)!

不能直接阶乘后做除法会溢出

百度后总结一下求组合数的几种方法(组合数combinatorial number)

1.递推法

可以通过公式:

Cmn=Cm1n+Cm1n1

递推求出,但是对于n太大的情况就不适用了

2.取对数法

为了避免直接计算n的阶乘,对公式两边取对数,于是得到:

ln(Cmn)=ni=1ln(i)mi=1ln(i)nmi=1ln(i)

通过取对数将连乘转化成了连加

化简一下得到:ln(Cmn)=ni=m+1ln(i)nmi=1ln(i)

之后Cmn=expln(Cmn)

3.拆分阶乘

这个方法其实把阶乘拆分成若干分式后用double来做
需要注意的是精度的处理问题
直接看题解了
知道做法后这道题还是挺水的

代码

#include<cstdio>#include<iostream>#include<cmath>#include<cstring>#include<cstdlib>#include<queue>using namespace std;#define uint unsigned intuint Comb(uint n,uint m)//¼ÆËã×éºÏÊý{    uint a=n+m;    uint b=min(n,m);    double ans=1.0;    while(b>0)    {        ans=ans*((double)(a--)/(double)(b--));    }    ans+=0.5;    return (uint)ans;}int main(){    uint n,m;    while(scanf("%u%u",&n,&m)!=EOF)    {         if(n==0 && m==0)break;         cout<<Comb(n,m)<<endl;    }}
0 0
原创粉丝点击