方程 C(c,m)*sigmai(0-m)sigmaj(0-(c-m)){(-1)^(m-i)(k/c)^n*C(m,i)*C(c-m,j)} /2^c
k=2*(i+j)-c
精度问题有点儿烦人...起初wa了,我以为是我精度有问题,今天才发现是少乘了俩组合数,其实这题对精度要求不是高.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define eps 1e-20
#define inf 1e10
int Sign(double x)
{
return x<-eps?-1:x>eps;
}
double Fabs(double x)
{
return (Sign(x)<0)?-x:(x>eps?x:0);
}
double Comb[105][105];
void Init_Comb()
{
int i,j;
memset(Comb,0,sizeof(Comb));
Comb[0][0]=1;
for(i=1;i<=100;++i)
for(j=0;j<=i;++j)
Comb[i][j]=Comb[i-1][j]+Comb[i-1][j-1];
// cout<<Comb[100][49]<<endl;
}
double Pow(double a,int n)
{
double ret=1.0;
// if(Fabs(a)<1&&n>=200)
// return 0;
while(n)
{
if(n&1)
ret*=a;
a*=a;
n>>=1;
}
// if(Sign(ret)==0)
// return 0;
return ret;
}
int main()
{
int c,n,m,i,j;
double k,ans,tmp;
Init_Comb();
while(scanf("%d",&c))
{
if(c==0)
break;
scanf("%d %d",&n,&m);
if((n-m)%2||m>c||m>n)
{
printf("0.000\n");
continue;
}
ans=0;
for(i=0;i<=m;++i)
{
for(j=0;j<=(c-m);++j)
{
k=2.0*(i+j)-c;
if((m-i)&1)
ans-=Pow(k/c,n)*Comb[m][i]*Comb[c-m][j];
else
ans+=Pow(k/c,n)*Comb[m][i]*Comb[c-m][j];
}
}
for(i=0;i<m;++i)
{
ans*=(double)(c-i)/((m-i)*2);
}
for(;i<c;++i)
ans/=2;
printf("%.3f\n",ans);
}
return 0;
}