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\n",ca++,ans); 35 } 36 return 0; 37 }
人生就像心电图,想要一帆风顺,除非game-over