• UVA11762概率期望


     1 /*UVA11762*/
     2 /*概率期望:
     3 题目:给出一个整数n,每次可以在不超过n的素数中随机选择一个p,如果p是n的约数,则n变成n/p,否则不变。
     4 问平均情况要多少次随机选择,才能把n变成1?
     5 解题步骤:举例、归纳方法
     6 举例:
     7 例N=13 ,可得素数2,3,5,7,11,13, 发现只有选到13时才能变成1,ans=1/p,p=1/6,ans=6;
     8 例N=15, 可得素数2,3,5,7,11,13,发现只能选到3,5;
     9          若选到3,N=5,素数2,3,5, 必须要选到5
    10          若选到5,N=3,素数2,3,  必须选到3
    11          p=(1/6)*(1/3)+(1/6)*(1/2) ans=1/p=36/5
    12 归纳:
    13 关键是求p(由上可看出是运用乘法,加法原理)
    14 递归方法:f(N)=sigm求和(1/Q[N]*f(N/i),2<=i<=N且i是素数且N%i==0),N>1;
    15                1,N=1;
    16           注意f(N)可以记忆化
    17           Q[N]=不超过n的素数的个数,例Q[15]=6,可预先求出
    18 但是可惜,上面的方法错了= =,换句话说,p是对的,而1/P不是答案
    19 改之:马尔可夫过程
    20 f(x)=1+f(x)*(Q(x)-g(x))/p(x)+sigm(f(x/y)/Q(x),y是素数因子,g(x)是y的总个数
    21 移项后化简:f(x)=(sigm(f(x/y))+Q(x))/g(x)
    22 */
    23 #include<iostream>
    24 #include<stdio.h>
    25 #include<string.h>
    26 #include<algorithm>
    27 #include<stdlib.h>
    28 #include<math.h>
    29 #include<queue>
    30 #include<vector>
    31 #include<map>
    32 
    33 using namespace std;
    34 
    35 const int maxn = 1000000;//素数打表
    36 bool flag[maxn+5];
    37 int prim[maxn/3], cnt;
    38 void calc_prim(){
    39     cnt=0;
    40     for(int i = 2; i <= maxn; i ++){
    41         if(!flag[i]) prim[cnt++] = i;
    42         for(int j = 0; j < cnt && prim[j]*i <= maxn; j ++){
    43             flag[i*prim[j]] = 1;
    44             if(i%prim[j]==0) break;
    45         }
    46     }
    47     return ;
    48 }//最终有cnt个素数prim[0]--prim[cnt-1]
    49 int Q[maxn+5];
    50 void builtQ()
    51 {
    52     calc_prim();
    53     Q[2]=1,Q[3]=2;
    54     for(int i=4;i<=maxn;i++)
    55     if (!flag[i]) Q[i]=Q[i-1]+1;else Q[i]=Q[i-1];
    56     //利用了素数非连续性的特点
    57     /*Q[x]=Q[x-1]+1,if x is prime,else Q[x]=Q[x-1]*/
    58 }
    59 double F[maxn+5];//记忆化搜索用
    60 double sigmp(int N)
    61 {
    62     if (F[N]!=-1.0) return F[N];
    63     double sum=0;int tot=0;
    64     for(int i=2;i<=N;i++)
    65     {
    66         if (!flag[i] && N%i==0) sum+=sigmp(N/i),tot++;
    67     }
    68     sum=(sum+Q[N])/tot;//累加上无法约简的部分
    69     return F[N]=sum;
    70 }
    71 int main()
    72 {
    73     int t,N;
    74     builtQ();
    75     /*memset(F,-1,sizeof(F));*/
    76     /*double 可以初始化为0,但不可以为-1*/
    77     for(int i=2;i<=maxn;i++) F[i]=-1.0;
    78     F[1]=0.0;
    79     cin>>t;
    80 
    81     for(int cas=1;cas<=t;cas++)
    82     {
    83         cin>>N;
    84         printf("Case %d: %.7lf
    ",cas,sigmp(N));
    85     }
    86     return 0;
    87 
    88 }
  • 相关阅读:
    VMware Workstation 6.0 正式版公布
    KMyMoney:全体理财好管家
    Bugzilla 3.0 公布
    Brightside:切换工作区的小东西
    QTM-Blogging 客户端
    MDF2ISO-将 MDF 转换为 ISO
    Yakuake 2.8 beta1
    Red Hat 的 Liberation 字体
    Dictman:有效的词典呆板人
    digiKam 0.9.2 Beta 1
  • 原文地址:https://www.cnblogs.com/little-w/p/3570257.html
Copyright © 2020-2023  润新知