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

该博客探讨了如何解决UVA10883问题,即计算一组数字的supermean。supermean可以通过不断将相邻数字求平均值直到只剩下一个数来求得。文中介绍了使用杨辉三角的组合数和对数运算来降低计算复杂度,通过递推公式log_ci = log_ci + log(n-1-i) - log(i+1)累推出组合数,并利用指数运算来计算最终答案。对于每个项,若x大于0则累加exp(log_ci + log(x) - log2_n),否则累减exp(log_ci + log(-x) - log2_n)。
摘要由CSDN通过智能技术生成

 题意: 给出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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值