Lightoj 1038 - Race to 1 Again (概率DP)

题目链接:

  Lightoj  1038 - Race to 1 Again

题目描述:

  给出一个数D,每次可以选择数D的一个因子,用数D除上这个因子得到一个新的数D,为数D变为1的操作次数的期望为多少?

解题思路:

  概率DP咯,对于只知道期望是:E(X) = X1*p(X1) + X2*p(X2) + …… + Xn*p(Xn)的窝,拿这个题目没有一点办法。然后看了讨论版,发现总会有一些神人存在。

  求操作次数的期望时,先设定第i个因子给期望的贡献为Ti,那么有:E = (T1 + T2 + T3 + ...... + Tn)  / n;

  根据期望的定理:从当前位置移动到目的地的平均步数。所以可得到:E50 = (E1+1)/6 + (E2+1)/6 + (E5+1)/6 + (E10+1)/6 + (E25+1)/6 + (E50+1)/6;

  E1 == 0,然后先后依次递推就好啦。 

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 typedef long long LL;
 9 const int maxn = 100010;
10 const int INF = 0x3f3f3f3f;
11 
12 double dp[maxn];
13 int main ()
14 {
15     int T;
16     scanf ("%d", &T);
17     memset (dp, 0, sizeof(dp));
18     for (int i=2; i<maxn; i++)
19     {
20         double num, ans;
21         num = -1;
22         ans = 0;
23         int nu = (int)sqrt (i);
24         for (int j=1; j<=nu; j++)
25         {
26             if (i%j == 0)
27             {
28                 num ++;
29                 ans += 1 + dp[j];
30                 if (j != i/j)
31                 {
32                     num ++;
33                     ans += 1 + dp[i/j];
34                 }
35             }
36             dp[i] = ans / num;
37         }
38     }
39     for (int t=1; t<=T; t++)
40     {
41         int n;
42         scanf ("%d", &n);
43         printf ("Case %d: %lf\n", t, dp[n]);
44     }
45     return 0;
46 }
posted @ 2015-11-10 18:19  罗茜  阅读(1155)  评论(0编辑  收藏  举报