UVA 11762 Race to 1

本文介绍了一种结合概率DP和记忆化搜索的方法来解决一个特定问题:给定一个正整数N,求出其所有素因子并计算在随机选取素数因子条件下将N分解至1所需的平均步骤数的期望。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接

题意:给定一个数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<cstdio>
#include<algorithm>
#include<cstring>
#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;i<n;i++)
    {
        if(isprime[i])
        prime[cnt++]=i;
        for(int j=0;j<cnt&&prime[j]*i<n;j++)
        {
            isprime[i*prime[j]]=false;
            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;j<cnt&&prime[j]<=n;j++)
    {
        tot++;
        if(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值