码迷,mamicode.com
首页 > 其他好文 > 详细

UVa 11762 (期望 DP) Race to 1

时间:2015-03-11 21:25:36      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

设f(x)表示x转移到1需要的次数的期望,p(x)为不超过x的素数的个数,其中能整除x的有g(x)个

则有(1-g(x)/p(x))的概率下一步还是转移到x,剩下的情况各有1/p(x)的概率转移到x/y

根据全期望公式,f(x) = 1 + (1-g(x)/p(x)) * f(x) + sum{ 1/p(x) * f(x/y) | y是能整除x且不超过x的素数 }

代码是用记忆化搜索计算f的

技术分享
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 using namespace std;
 5 
 6 const int maxn = 1000000;
 7 bool vis[maxn + 10];
 8 int prime[100000], pcnt = 0;
 9 
10 void prime_table()
11 {
12     int m = sqrt(maxn + 0.5);
13     for(int i = 2; i <= m; i++) if(!vis[i])
14         for(int j = i*i; j <= maxn; j += i) vis[j] = true;
15     for(int i = 2; i <= maxn; i++) if(!vis[i]) prime[pcnt++] = i;
16 }
17 
18 double d[maxn + 10];
19 
20 double dp(int x)
21 {
22     if(x == 1) return 0;
23     if(vis[x]) return d[x];
24     vis[x] = 1;
25     double& ans = d[x];
26     int p = 0, g = 0;
27     for(int i = 0; i < pcnt && prime[i] <= x; i++)
28     {
29         p++;
30         if(x % prime[i] == 0) { ans += dp(x / prime[i]); g++; }
31     }
32     ans = (ans + p) / g;
33     return ans;
34 }
35 
36 int main()
37 {
38     //freopen("in.txt", "r", stdin);
39 
40     prime_table();
41     memset(vis, false, sizeof(vis));
42     int T;
43     scanf("%d", &T);
44     for(int kase = 1; kase <= T; kase++)
45     {
46         int x;
47         scanf("%d", &x);
48         printf("Case %d: %.10f\n", kase, dp(x));
49     }
50 
51     return 0;
52 }
代码君

 

UVa 11762 (期望 DP) Race to 1

标签:

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/4330900.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!