dp[i]表示从i到1的期望次数。
dp[i] = ∑dp[j] / cnt + 1。(cnt为所有因子数量,含1和i)但是∑dp[j]中有一个dp[i]。把dp[i]都移项到左侧,得dp[i] = (∑dp[j] - dp[i] + cnt) / (cnt - 1)。提前预处理出来,O(1)回答即可。
1 #include <cstdio>
2 #include <cmath>
3 using namespace std;
4 double dp[100100];
5 int n,T,cas;
6 int main()
7 {
8 dp[1] = 0;
9 for (int i = 2;i <= 100000;i++)
10 {
11 int t = sqrt(i),cnt = 2;
12 double sum = 0;
13 for (int j = 2;j <= t;j++)
14 if (i % j == 0)
15 {
16 cnt++;
17 sum += dp[j];
18 if (i / j != j)
19 {
20 cnt++;
21 sum += dp[i / j];
22 }
23 }
24 dp[i] = (sum + cnt) / (cnt - 1);
25 }
26 for (scanf("%d",&T);T != 0;T--)
27 {
28 cas++;
29 scanf("%d",&n);
30 printf("Case %d: %.6lf\n",cas,dp[n]);
31 }
32 return 0;
33 }