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);

    }

}

 

你可能感兴趣的:(ide)