UVA 11762 Race to 1

题目链接

题意:给定一个数N, 要你从小于等于N的素数中找出能够给N整除的素因子, 即该素数可以被N整除, 使得新的N = N/prime[i], 数N=N除以该素因子得到新的N, 知道N=1为止, 现在要你求出平均情况下随机选素数的次数的期望.

分析:概率dp+记忆化搜索。设dp[i]为i的期望,fac为素因子的数量,tot为素数数量,,则dp[i]=1+(1-fac/tot)*dp[i]+Σdp[i/pk]/tot整理得dp[i]=(tot+Σdp[i/pk])/fac;

#include
#include
#include
#define MAX_N 1000001
using namespace std;
double dp[MAX_N];
bool isprime[MAX_N];
int prime[MAX_N];
int cnt;
void euler_sieve(int n)
{
    cnt=0;
    memset(isprime,true,sizeof(isprime));
    isprime[0]=false;
    isprime[1]=false;
    for(int i=2;iif(isprime[i])
        prime[cnt++]=i;
        for(int j=0;jfalse;
            if(!(i%prime[j]))
            break;
        }
    }
    return ;
}
double DP(int n)
{
    if(n==1)
    return 0;
    if(dp[n])
    return dp[n];
    double ans=0;
    int fac=0;
    int tot=0;
    for(int j=0;jif(n%prime[j]==0)
        {
            fac++;
            ans+=DP(n/prime[j]);
        }
    }
    ans=((double)tot+ans)/(double)fac;
    return dp[n]=ans;
}
int main(void)
{
    memset(dp,0,sizeof(dp));
    euler_sieve(MAX_N);
    int cas=1;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        printf("Case %d: %.10lf\n",cas++,DP(n));
    }
    return 0;
}

你可能感兴趣的:(DP)