这道题开始没有注意越界问题,当 n = 5000 是取组合数非常大,而 2^n 也非常大,需要用自然对数处理一下才能处理 C(N,K)*A[k]/2^N 的求值,而且取对数的时候要分正负零各种情形考虑,提交了很多次,终于 AC 了。
package UVa10883;
import java.util.Scanner;
public class Main {
public static double solve(double[] v, int len) {
long n = len - 1;
double lgc = 0, lgd = n*Math.log(2);
double sum = 0, f;
if ( v[0] > 0 )
sum += Math.exp(Math.log(v[0]) + lgc - lgd);
else if ( v[0] < 0 )
sum -= Math.exp(Math.log(-v[0]) + lgc - lgd);
for ( int i=1; i<=n; i++ ) {
lgc = lgc + Math.log(n-i+1) - Math.log(i);
if ( v[i] > 0 ) {
f = Math.log(v[i]) + lgc -lgd;
sum += Math.exp(f);
} else if ( v[i] < 0 ) {
f = Math.log(-v[i]) + lgc -lgd;
sum -= Math.exp(f);
}
}
return sum;
}
public static void main(String[] args) {
double[] v = new double[51000];
Scanner in = new Scanner(System.in);
int N = in.nextInt();
for ( int i=0; i<N; i++ ) {
int n = in.nextInt();
for ( int j=0; j<n; j++ ) {
v[j] = in.nextDouble();
}
double r = solve(v,n);
System.out.printf("Case #%d: %.3f%n", i+1, r);
}
}
}