Problem
紳士們上小便的時候,彼此之間會隔著 K 個小便斗 (空著人的小便斗),請問當有 N 個一排的小便斗,請問壅塞個數的期望值為何 (一次平均可以多少人上小便)。
Sample Output
1 2 3
| Case #1: 1.5000 Case #2: 2.2857 Case #3: 2.4133
|
Solution
狀態紀錄 dp[i]
表示 i 個一排的小便斗的壅塞期望值。
現在考慮最後一個進入的人所佔的位置 p
,則期望值會等於 1 + dp[p-K-1] + dp[i-(p+K)]
,分別為左側和右側的期望值,儘管左右兩側狀態也會對邊界有空隙 <= K,但是放入之後與 p 之間空隙最 <= 2K,也塞不下其他人 (至少要 2K + 1)。
由於最後一個人的情況有 i 種,每一種的機率都相同,因此推導結果為 dp[i] = 1 + (dp[1] + dp[2] + ... + dp[i-k-1])/i
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| #include <stdio.h> #include <math.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <map> #include <set> #include <string.h> #include <assert.h> using namespace std; double dp[1048576], sum[1048576]; int main() { int testcase, cases = 0; int n, m; scanf("%d", &testcase); while (testcase--) { scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++) { if (i <= m) { dp[i] = 1; } else { dp[i] = 1 + sum[i - m - 1] * 2.0 / i; } sum[i] = sum[i - 1] + dp[i]; } printf("Case #%d: %.4lf\n", ++cases, dp[n]); } return 0; }
|