UVa10375 - Choose and divide

紫薯上刘汝佳写的啥玩意啊,看不懂看不懂

 

google之

发现这么一个公式:

C(n,k)=C(n,k1)(nk+1)/k

有了这个公式,那么我们就可以对其进行递推了

C(p,q)=(p-q+1)/q*C(p,q-1)

即:

for (i=1;i<=q;i++)
    ans = ans * (p-i+1) / i;

边乘边除可以避免越界,代码如下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<list>
#include<string>
#include<cmath>
#include<sstream>
#include<ctime>
#define _PI acos(-1.0)
#define INF 1 << 10
#define esp 1e-6
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
/*===========================================
===========================================*/
int p,q,r,s,i;
double ans;
int main(){
    while (~scanf("%d%d%d%d",&p,&q,&r,&s)){
        ans=1.0;
        if (p - q < q) q = p - q;
        if (r - s < s) s = r - s; //两行优化,省一半的时间
        for (i=1;i<=q||i<=s;i++){
            if(i <= q) ans = ans * (p-i+1) / i;
            if(i <= s) ans = ans * i / (r-i+1);
        }
        printf("%.5lf\n", ans);
    }
}

 

posted @ 2015-05-26 22:56  ACBingo  阅读(206)  评论(0编辑  收藏  举报