对二项式的复习:
- 如果a==1&&b==1,那么可以得出C(n,1)+C(n,2)+C(n,3)+…….+C(n,n)=2^n
- 如果a==1&&b==-1,那么C(n,0)-C(n,1)+C(n,2)-C(n,3)+……(-1)^n*C(n,n)=0
- C(n,0)+C(n,2)+C(n,4)+……=C(n,1)+C(n,3)+C(n,5)+……=2^(n-1)
- Cnk=n!/(n-k)!/k!
题目链接:
https://vjudge.net/problem/UVA-10883
分析:
多谢两组数据可以看出其系数满足杨辉三角;则ans=sum(C(n-1,i)*a[i])/(2^(n-1)),因为n太大,2^(n-1)存储不下,故用对数存储。即ans=sum(pow(2,log2^(C(n-1,i))+log2^a[i]-(n-1)));
先处理log2^(C(n-1,i))=log2^((n-1)!/(n-1-i)!/i!;
那么log2^(C(n-1,i-1))=log2^( (n-1)!/(n-i)!/(i-1)! );
令f[i]代表log2^(C(n-1,i)),则log_2_C[i]/log_2_C[i-1]=log2^(n-i)/i=log2^(n-i)-log2^i;
得出递推公式: f[i]=f[i-1]+log2^(n-i)-log2^i;
代码如下:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<cmath>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=50000+5;
double log_2_C[maxn];
int main()
{
int T;
scanf("%d",&T);
int kase=0;
while(T--)
{
memset(log_2_C,0,sizeof(log_2_C));
int n;
scanf("%d",&n);
//得出C(n-1,i)
log_2_C[0]=1;
for(int i=1;i<=n;i++)
{
log_2_C[i]=log_2_C[i-1]+log(n-i)/log(2)-log(i)/log(2);
}
double x;
double res=0;
for(int i=0;i<n;i++)
{
scanf("%lf",&x);
if(x>0) //如果x大于0
{
res+=pow(2,(log(x)/log(2)+log_2_C[i]-n+1));
}
else //如果x小于0
res-=pow(2,(log(-x)/log(2)+log_2_C[i]-n+1));
}
printf("Case #%d: %.3lf\n",++kase,res/2);
}
}