UVA 1639(组合数学)

根据组合数公式C(m,n),由于m可能达到20万,因此转换为ln,之后可以表达为ln(m!)-ln(n!)-ln((m-n)!);

求每一个c[n]时,也要根据杨辉三角求组合数进行转化。

注意long double输出一般要用cout, printf不好使。

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cmath>
 5 #define repu(i,a,b) for(int i=a;i<b;i++)
 6 using namespace std;
 7 const int INF = 1000000000;
 8 #define ll long long
 9 const int N = 200005;
10 double c[N*2];
11 
12 double logC(int n,int m)
13 {
14     return c[n]-c[m]-c[n-m];
15 }
16 
17 int main()
18 {
19     int n;
20     double p;
21     for(int i = 1; i <= N*2; i+=1)///杨辉三角求组合数
22         c[i] = c[i-1] + log(i);
23     int ca = 1;
24     while(~scanf("%d%lf",&n,&p))
25     {
26         double ans = 0.00;
27         repu(i,1,n+1)
28         {
29             long double t = logC(2*n-i,n);
30             long double v1 = t + (n+1)*log(p) +   (n-i)*log(1-p);
31             long double v2 = t + (n+1)*log(1-p)+  (n-i)*log(p);
32             ans += i*(exp(v1)+exp(v2));
33         }
34         printf("Case %d: %.6lf
",ca++,ans);
35     }
36     return 0;
37 }
View Code
原文地址:https://www.cnblogs.com/ACMERY/p/4335813.html