lightoj1038(数学期望dp)

题意:输入一个数N,N每次被它的任意一个因数所除 变成新的N 这样一直除下去 直到 N变为1

求变成1所期望的次数

解析:

d[i] 代表从i除到1的期望步数;那么假设i一共有c个因子(包括1和本身)

d[i] = ( d[1] + d[a2] + d[a3] + d[a4] ..... + d[i] + c) / c; (加c是因为每一个期望值都会加1,因为多出一步才变成它(即第一次从i到它的因子的那一步))

 把右边的dp[i] 移到左边 化简得

dp[i] =  ( d[1] + d[a2] + d[a3] + d[a4] ..... + d[i-1] + c) / (c-1)

注意:不能太暴力求因数,折半求  还有。。。。mmp。。不要用Java做。。。。

这一题与lightoj1030 的思路一样 都是期望dp 

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int maxn = 100005;
int cnt;
int main() {
    int res = 0;
    double dp[maxn];
    mem(dp,0);
    int temp;
    for(int i=2;i<maxn;i++)
    {
        cnt = 0;
        double sum = 0;
        for(int j=1;j<=sqrt(i+0.5);j++)
        {
            if(i % j == 0)
            {
                sum += dp[j];
                cnt++;
                if(j != i/j){
                    sum += dp[i/j];
                    cnt++;
                }
            }


        }
        dp[i] = (sum + cnt)/(double)(cnt-1);
    }
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&temp);
        printf("Case %d: %.10f\n",++res,dp[temp]);
    }

    return 0;
}

猜你喜欢

转载自www.cnblogs.com/WTSRUVF/p/9053401.html