uva10883 - Supermean-杨辉三角+log应用

来源:互联网 发布:电子书软件哪个好 编辑:程序博客网 时间:2024/06/07 18:29

 题意: 给出n个数字, 要求你求出它们的supermean, supermean的定义是: n个数先两两相邻

        求平均值, 那么得到n-1个数, 已知循环做这件事, 直到剩下的数字只有1个


 

可以比较容易推导出  最后的ans= 每一项之和,其中通项为 C【i】*Ai /2^(n-1)

Ci是 C(n-1,i)也就是杨辉三角第n-1行的第i个


由于n太大了,直接算CI和2^n 都是不行的,由于答案是浮点的,我们可以利用log函数降次

根据组合数递推的公式              log_ci=log_ci+log(n-1-i)-log(i+1); 可以累推出ci

计算每一项,则先对其取对数,降次,最后再取回指数。

  if(x>0)
            ans+=   exp(  log_ci+log(x) -log2_n) ;
             else ans-= exp(  log_ci+log(-x) -log2_n) ;


#include <cstdio>#include <cmath>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <set>#include <vector>#include <iostream>using namespace std;typedef long long   ll;const int maxn=490000+5;int main(){    //cout<<log(2.7182818284590452353602874713527)<<endl;    //  printf("%lf\n",C(5000,3000));    int t;    cin>>t;    int cnt=1;    while(t--)    {        int n;        scanf("%d",&n);        double log2_n=(n-1)*log(2.0);        double ans=0;        double x;        double log_ci=log(1);        for (int i=0; i<n; i++)        {            scanf("%lf",&x);            if(x>0)            ans+=   exp(  log_ci+log(x) -log2_n) ;             else ans-= exp(  log_ci+log(-x) -log2_n) ;             log_ci=log_ci+log(n-1-i)-log(i+1);        }        printf("Case #%d: %.3lf\n",cnt++,ans );    }    return 0;}


0 0