LightOJ 1038 Race to 1 Again 概率DP

Race to 1 Again LightOJ - 1038

对于一个整数 DD,每次从他的因数中选一个 dd,然后令 D=D/dD=D/d,直到 D=1D=1 为止,问从 DD11 执行这样操作的期望次数。

E[i]E[i] 表示整数 ii 变为 11 的期望次数,nn 表示因子的总个数,a[k]a[k] 表示第 kk 个因子,第 11 个因子 a[1]=1a[1]=1,第 nn 个因子 a[n]=ia[n]=i,则:

E[i]=1nk=1n(E[a[k]]+1)E[i]=E[i]n+1nk=2n1E[a[k]]+1n1nE[i]=1nk=2n1E[a[k]]+1E[i]=1n1(k=2n1E[a[k]]+n) \begin{aligned} E[i]&=\frac{1}{n}\sum_{k=1}^n(E[a[k]]+1)\\ E[i]&=\frac{E[i]}{n}+\frac{1}{n}\sum_{k=2}^{n-1}E[a[k]]+1\\ \frac{n-1}{n}E[i]&=\frac{1}{n}\sum_{k=2}^{n-1}E[a[k]]+1\\ E[i]&=\frac{1}{n-1}(\sum_{k=2}^{n-1}E[a[k]]+n)\\ \end{aligned}

代码如下:

#include<iostream>
#include<cstdio>
//#define WINE
#define MAXN 100010
using namespace std;
double d[MAXN];
int n,j,T,iCase;
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    d[0]=d[1]=0;
    for(int i=2;i<MAXN;i++){
        n=0;
        for(j=2;j*j<i;j++){
            if(i%j==0){
                n+=2;
                d[i]+=d[j];
                d[i]+=d[i/j];
            }
        }
        if(j*j==i){
            n+=1;
            d[i]+=d[j];
        }
        n+=2;// 1 and i
        d[i]+=n;
        d[i]/=(n-1);
    }
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        printf("Case %d: %.6lf\n",++iCase,d[n]);
    }
    return 0;
}

在这里插入图片描述

posted @ 2020-03-24 20:15  winechord  阅读(97)  评论(0编辑  收藏  举报