码迷,mamicode.com
首页 > 其他好文 > 详细

[期望dp+记忆化搜索] light oj 1038 Race to 1 Again

时间:2015-04-29 11:38:32      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

题意:

给一个数n,每次随机选它的一个约数去除n,直到除到1为止,问除的次数的期望。

思路:

E[n]= E[n/a[1]]/cnt+E[n/a[2]]/cnt+...+E[n/a[n]]/cnt+1

a[i]为n的约数,cnt为约数的个数。

显然a[i]=1  则(1-1/cnt)E[n]=E[n/a[2]]/cnt+...+E[n/a[n]]/cnt+1

记忆化搜索就ok了~

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
#include"stack"
#include"vector"
#define ll __int64
#define eps 1e-8
#define inf -999999999999999999LL
using namespace std;
double dp[123567];
double dfs(int x)
{
    if(x==1) return 0.0;
    if(fabs(dp[x]+1)>eps) return dp[x];
    int cnt=0;
    double ans=1.0;
    int lit=sqrt(x*1.0);
    for(int i=1; i<=lit; i++)   //统计因子数
    {
        if(x%i==0)
        {
            if(i*i==x) cnt++;
            else cnt+=2;
        }
    }
    for(int i=1; i<=lit; i++)  //求期望的和
    {
        if(x%i==0)
        {
            if(i*i==x) ans+=1.0/cnt*dfs(x/i);
            else
            {
                if(i!=1) ans+=1.0/cnt*dfs(x/i);
                ans+=1.0/cnt*dfs(i);
            }
        }
    }
    ans=ans/(1-1.0/cnt);
    return dp[x]=ans;
}
int main()
{
    int t,cas=1;
    cin>>t;
    memset(dp,-1,sizeof(dp));
    while(t--)
    {
        int n;
        scanf("%d",&n);
        printf("Case %d: %.7f\n",cas++,dfs(n));
    }
    return 0;
}


[期望dp+记忆化搜索] light oj 1038 Race to 1 Again

标签:

原文地址:http://blog.csdn.net/wdcjdtc/article/details/45363725

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!