Race to 1 Again(LightOJ-1038) 纯概率DP

Rimi learned a new thing about integers, which is - any positive integer greater than 1 can be divided by its divisors. So, he is now playing with this property. He selects a number N. And he calls this D.

In each turn he randomly chooses a divisor of D (1 to D). Then he divides D by the number to obtain new D. He repeats this procedure until D becomes 1. What is the expected number of moves required for N to become 1.

Input

Input starts with an integer T (≤ 10000), denoting the number of test cases.

Each case begins with an integer N (1 ≤ N ≤ 105).

Output

For each case of input you have to print the case number and the expected value. Errors less than 10-6 will be ignored.

Sample Input

3

1

2

50

Sample Output

Case 1: 0

Case 2: 2.00

Case 3: 3.0333333333

题意:这道题的话就是,给你一个数,用它的因子去除它,循环重复这个过程,直至这个数变成1,问需要多少次。

思路:看起来问多少次是一个期望问题,但这个不是单纯的期望dp,举个例子,比如50。50的因子为{1,2,5,10,25,50}。显而易见,用因子去除一个数剩下的数还是他的因子,假如现在剩下的数是10,那么问题就转化为了把10变成1需要几次的问题。从这里我们可以看出,50需要的次数(我们记为E(50))取决于1,2,5,10,25,50出现的次数。这就注定了我们的计算顺序是从前往后依次计算的。
假设数X的因子个数是为N,则
f(X) = 1/N * (f(X1) + f(X2) + … +f(X))
由于在此时f(X)在此时是未知的,我们呢就将式子化简一下。
最终化简成 f (X) = 1/(N-1) * (f(X1) + f(X2) + … +f(X(N-1)))
用一个函数在之前将左右的f(x)算好即可。

AC代码:

#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include<iomanip>
typedef long long ll;
const int maxx=100010;
const int inf=0x3f3f3f3f;
using namespace std;
double f[maxx];
void solve()
{
    f[1]=0;
    for(int i=2;i<=100000;i++)
    {
        int cnt=-1;
        double sum=0;
        for(int j=1;j<=sqrt(i);j++)
        {
            if(i%j==0)
            {
                cnt++;
                sum+=f[j]+1;
                if(j*j!=i)
                {
                    cnt++;
					sum+=f[i/j]+1;
                }
            }
        }
        f[i]=sum/cnt;
    }
}
int main()
{
    int t;
    cin>>t;
    solve();
    for(int i=1;i<=t;i++)
    {
        int x;
        cin>>x;
        cout<<"Case"<<" "<<i<<":"<<" "<<fixed<<setprecision(6)<<f[x]<<endl;
    }
    return 0;
}
发布了204 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43846139/article/details/104016508