Light OJ 1038 Race to 1 Again (期望DP)

来源:互联网 发布:freepic2pdf mac 编辑:程序博客网 时间:2024/06/04 19:21

题意: He selects a number N. And he calls this D.In each turn he randomly chooses a divisor of D (1 to D). Then he divides D by the number to obtain new D. He repeats this procedure until D becomes 1. What is the expected number of moves required for N to become 1.

解析:设dp[x]为x到1的期望步数,p是x的因子个数。

dp[x] = (dp[a1]+dp[a2]+.....+dp[ap])/p + 1

a1 ......ap是x的p个因子。

将n的所有因子按顺序保存在数组中,再按上述方式dp。

[code]:

#include<cstdio>#include<cstring>#include<algorithm>#include<cstdlib>#include<cmath>using namespace std;const int inf = 0x3f3f3f3f;int n,m,a[200];double dp[200];double sol(){    int i,j,cnt;    m = 0;    for(i = 1;i*i <= n;i++){        if(n%i==0){            a[m++] = i;            if(i*i!=n) a[m++] = n/i;        }    }    sort(a,a+m);    dp[0] = 0;    for(i = 1;i < m;i++){//printf("%d ",a[i]);        dp[i] = 0;cnt = 0;        for(j = 0;j < i;j++){            if(a[i]%a[j]==0){                dp[i] += dp[j];                cnt++;            }        }        dp[i]/=cnt;        dp[i]+=1.0*(cnt+1.0)/cnt;    }//putchar('\n');    return dp[m-1];}int main(){    int i,j,t,cas,T;    scanf("%d",&cas);    for(T = 1;T <= cas;T++){        scanf("%d",&n);        printf("Case %d: %.8f\n",T,sol());    }    return 0;}


0 0