LightOJ1038---Race to 1 Again (概率dp(基础))

【题目来源】https://cn.vjudge.net/problem/LightOJ-1038
【题意】
给出一个数大于1的N,每次除以任意的一个他的因子,直到变为1,问从N除到1的次数的期望。
【思路】
递推,设该数为D,有N个因子,分别是1,n1,n2,n3…nn-2,D,
那么选到每个因子的概率都是1/N,除非选到D,不然选到其他因子的话都要多1步,然后再计算D除以该因子的期望
这就能得到公式了,设dp[D]为数D按规则变成1的期望步数
那么dp[D] = 1/N * (dp[D/1] + 1) + 1 / N * (dp[D/n1] + 1) + 1/ N * (dp[D/n2] + 1) + … + 1/N * (dp[D/nn-2] + 1) + 1/N * (dp[D / D] + 1)
化简得 dp[D] = 1 / (N-1) * (dp[D/n1] + dp[D/n2] + … + dp[D/nn-2] + N)。
还有,cout输出的double精度和printf输出的精度有区别。
参考:http://blog.csdn.net/l123012013048/article/details/46361365

#include<bits/stdc++.h>
using namespace std;
double dp[100000+10];
int main()
{
    dp[1]=0;
    dp[2]=2;
    for(int i=3;i<=100000;i++)
    {
        dp[i]=0;
        int num=0;
        for(int j=1;j*j<=i;j++)
        {
            if(i%j==0)
            {
                num++;
                dp[i]+=dp[j];
                if(i/j!=j)
                {
                    num++;
                    dp[i]+=dp[i/j];
                }
            }
        }
        dp[i]=(dp[i]+num)/(num-1);
    }
    int T,cases=1;
    cin>>T;
    while(T--)
    {
        int n;
        cin>>n;
        printf("Case %d: %lf\n",cases++,dp[n]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值