您的位置:首页 > 其它

uva10883 - Supermean 杨辉三角

2014-06-17 17:16 253 查看
Do you know how to compute the mean (or average) of
n
numbers?Well, that's not good enough for me. I want the supermean! "What's asupermean," you ask? I'll tell you. List the
n given numbers innon-decreasing order. Now compute the average of each pair of adjacentnumbers. This will give you
n - 1 numbers listedin non-decreasing order. Repeat this process on the new list of numbersuntil you are left with just one number - the supermean. I tried writinga program to do this, but it's too slow. :-( Can you help me?
Input

The first line of input gives the number of cases, N.N test cases follow. Each one starts with a line containingn (0<n<=50000). The next line will containthe
n input numbers, each one between -1000 and 1000, in non-decreasingorder.
Output

For each test case, output one line containing "Case #x:" followed by the supermean, rounded to 3 fractional digits.
Sample InputSample Output
4
1
10.4
2
1.0 2.2
3
1 2 3
5
1 2 3 4 5

Case #1: 10.400
Case #2: 1.600
Case #3: 2.000
Case #4: 3.000

写出来是一个倒三角形,这个倒三角形也是N个正杨辉三角(分别以每个元素为顶点)的交叉,倒三角形最下面顶点的数相当于正杨辉三角第N行所有元素的和。

因此每个数的次数是杨辉三角第N行的系数,最后再除以2^(N-1)。

递推超时,因为只求一行,C(n,m)=C(n,m-1)*(n-m+1)/m,这里N很大,组合数太大,求组合数后除以2^(n-1)的结果不大。每一项可以表示成e^ln(C(N,i)*a[i]/2^(N-1))=e^(ln(C(N,i)+ln(a[i])-(N-1)*ln2)。lnC(N,i)=lnC(N,i-1)+ln(N-i+1)-ln(i),也就是不递推C(N,i),而递推lnC(N,i),在计算过程中以ln的形式把2^(N-1)除掉,最后在用exp算出结果。

注意正负问题。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int T,N;
int main(){
freopen("in.txt", "r", stdin);
int cas=0;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
N--;
double ans=0,pre=0,t;
scanf("%lf",&t);
if(t<0) ans-=exp(log(-t)-N*log(2));
else ans+=exp(log(t)-N*log(2));
for(int i=1;i<=N;i++){
pre+=log(N-i+1)-log(i);
scanf("%lf",&t);
if(t<0) ans-=exp(pre+log(-t)-N*log(2));
else ans+=exp(pre+log(t)-N*log(2));
}
printf("Case #%d: %.3lf\n",++cas,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: