UVA 1639(组合数学)

时间:2021-10-28 20:21:52

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

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

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

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#define repu(i,a,b) for(int i=a;i<b;i++)
using namespace std;
const int INF = ;
#define ll long long
const int N = ;
double c[N*]; double logC(int n,int m)
{
return c[n]-c[m]-c[n-m];
} int main()
{
int n;
double p;
for(int i = ; i <= N*; i+=)///杨辉三角求组合数
c[i] = c[i-] + log(i);
int ca = ;
while(~scanf("%d%lf",&n,&p))
{
double ans = 0.00;
repu(i,,n+)
{
long double t = logC(*n-i,n);
long double v1 = t + (n+)*log(p) + (n-i)*log(-p);
long double v2 = t + (n+)*log(-p)+ (n-i)*log(p);
ans += i*(exp(v1)+exp(v2));
}
printf("Case %d: %.6lf\n",ca++,ans);
}
return ;
}