不难发现结果可用二项式定理表示,即:sum{C(n-1,i)*a[i]/2^(n-1)}。本来以为是道水题,结果精度问题搞得我WA了n次。因为n太大,直接乘除肯定会溢出。所以先求log一下,然后再exp一下,组合数可以通过logC(n,k+1)=logC(n,k)+log(n-k)-log(k+1)递推得到。另外,因为a[i]可能为负数,所以在取对数的时候还得特殊处理一下。
#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define M 50010
double a[M];
int n;
double eps=1e-10;
int main()
{
freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
for(int kase=1;kase<=T;kase++)
{
printf("Case #%d: ",kase);
scanf("%d",&n);
for(int i=0;i<n;i++) scanf("%lf",&a[i]);
double ans=0;
double c=0;
for(int i=0;i<n;i++)
{
if(a[i]>0)
ans+=exp(c+log(a[i])-(n-1)*log(2));
else if(a[i]<0)
ans-=exp(c+log(-a[i])-(n-1)*log(2));
c=c+log(1.0*(n-1-i))-log(1.0*(i+1));
}
printf("%.3f\n",ans);
}
return 0;
}