程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> UVA 10883 - Supermean(組合數學+數值優化)

UVA 10883 - Supermean(組合數學+數值優化)

編輯:C++入門知識

題目鏈接:10883 - Supermean

題意:求超級平均數,就是相鄰兩個算一個平均數,直到剩下一個數,求數值。 思路:畫圖很容易推斷出公式。就拿最後一組樣例來說 1 2 3 4 5 1.5 2.5 3.5 4.5 2 3 4 2.5 3.5 3 觀察可以發現都是從頂到底,看又幾條路線,就有幾次,然後最後每個數字在除上相應次數的2,那幾條路線就是C(n - 1, [0 - n - 1])的組合數。 所以ans = sum{C(n - 1, i) * a[i] / 2^(n - 1)} 然後由於n很大,直接算會悲劇的。 所以每一項都先取log值,最後在次方乘回去,那麼每一項為 log(C(n - 1, i) * a[i] / 2^(n - 1)) = log(C(n - 1, i)) + log(a[i]) - (n - 1) * log(2); 最後再利用exp函數計算回去,從而求出總和即可 代碼:
#include 
#include 
#include 
#define min(a,b) ((a)<(b)?(a):(b))
const int N = 50005;
int t, n;
double a, c;

double cal(int i, double a) {
	return c + log(a) - (n - 1) * log(2);
}

int main() {
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		double sum = 0;
		c = 0;
		for (int i = 0; i < n; i++) {
			scanf("%lf", &a);
			if (a < 0) sum -= exp(cal(i, -a));
			else sum += exp(cal(i, a));
			c = c + log(n - i - 1) - log(i + 1);
		}
		printf("Case #%d: %.3lf\n", ++cas, sum);
	}
	return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved