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 }