Problem Description
小H是一个程序员。但是他很喜欢一些新奇的东西。
有一次,他去找物理实验室的朋友玩。他见到了一串非常有意思的粒子。N个粒子排成一排。每一秒中,每一段连续的粒子中会随意有一个爆炸,爆炸后该粒子就消失了,且将原来连续的一段粒子分隔成两段。
小H希望知道所有粒子都爆炸完的期望时间。
Input
第一行为一个整数T(1 <= T<= 400),表示有T组测试数据;
每组数据一个正整数N(1<=N<=400),表示一开始的粒子数。
Output
对于每组数据,输出期望时间(秒)。保留五位小数。
1 #include <stdio.h> 2 #include <math.h> 3 #define N 400 4 double map[N + 5]; 5 void initilizing() 6 { 7 int i, j, n; 8 map[0] = 0; 9 map[1] = 1; 10 map[2] = 2; 11 double temp; 12 for (n = 3; n <= N; n++) 13 { 14 temp = 0; 15 if (n % 2 == 0) //偶数 16 { 17 for (j = n / 2; j < n; j++) 18 temp += map[j]; 19 map[n] = 1 + temp * 2 / n; 20 } 21 else 22 { 23 for (j = (n + 1) / 2; j < n ; j++) 24 temp += map[j]; 25 map[n] = 1.0 * (n - 1) / n + temp * 2 / n + (1 + map[(n - 1) / 2]) / n; 26 } 27 } 28 } 29 int main() 30 { 31 int t, num, count, max, i, j, k; 32 double a, b; 33 scanf("%d", &t); 34 initilizing(); 35 while (t--) 36 { 37 scanf("%d", &num); 38 printf("%.6f\n", map[num]); 39 } 40 return 0; 41 }
idea
firstly, we should get the form, then according the form and input, gain the result.
f(1) = 1;
f(2) = 2;
f(3) = 2/3 * (1 + f(2)) + 1/3 * (1 + f(1))
f(4) = 2/4 * (1 + f(3)) + 2/4 * (1 + f(2))
f(5) = 2/5 * (1 + f(4)) + 2/5 * (1 + f(3)) + 1/5 * (1 + f(2))
then u can get the recursion formula
when n is even number
f(n) = 2/n * (n/2 + f(n-1) + f(n-2) + ... + f(n/2))
when n is odd number
f(n) = 2/n * ((n - 1) / 2 + f(n - 1) + f(n - 2) + ... + f((n - 1) / 2)) + 1/n * (1 + f((n - 1) / 2))