Race to 1 Again [概率]

来源:互联网 发布:网络用语 夯是什么意思 编辑:程序博客网 时间:2024/06/06 04:35

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=76505#problem/C

题目大意:给一个数n,从n随机选一个【1,n】的约数除,然后得到新n,反复操作直到n等于1,求操作次数的期望;

题目分析:

期望dp: 对于期望往往是倒着求,dp[ i ]表示i->1的期望次数,必然是dp[ 1 ]=0,这是最终状态,然后得出 2,3,4.......n的;

当前状态:  dp[i]=                  1                       +             dp[i]/cnt             +             dp[j]/cnt;

                             < 这一状态到下一状>                 <约数为1时>                 <约数为 2->n >

                             < 态次数+1转移       >      




代码:

//author:ACsorry//result:Yes#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<vector>#include<string>#include<queue>#include<deque>#include<stack>#include<map>#include<set>#define INF 1<<29#define maxInt 0x7fffffff#define SUP 0x80000000#define mem(a,b) memset(a,b,sizeof(a))using namespace std;typedef long long LL;const int N=100007;double dp[N];int main(){    int T;    scanf("%d",&T);    dp[1]=0;    for(int i=2;i<=100000;i++)    {        int cnt=2;        dp[i]=dp[1];        int j;        for(j=2;j*j<i;j++)        {            if(i%j==0)            {                cnt+=2;//这个地方加2,做得时候忽略了                dp[i]+=dp[i/j]+dp[j];            }        }        if(j*j==i)        {            cnt++;            dp[i]+=dp[j];        }        dp[i]=(dp[i]/cnt+1.0)*cnt/(cnt-1.0);    }    int cas=0;    while(T--)    {        int n;        scanf("%d",&n);        printf("Case %d: %.10lf\n",++cas,dp[n]);    }    return 0;}


0 0