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 }
本文为博主原创文章,未经博主允许不得转载。