24 概率与期望

Race to 1 Again

 LightOJ - 1038 

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

题目的意思是给你一个数字n,每一次你可以选择一个n的一个约数然后除以他得到n‘’,一直到这个数字变成1

有期望公式我们知道有E(X) = x1*p(x1)+ x2 *p(x2) + x3*p(x3)+...................................+ xn*p(xn) ;

但是这个期望公式对这个题目没有任何的意义,假设这个数字有num个因数(包括他本身),那么这个数字到1

的次数的期望是E(X)= (E(a[1])  + E(a[2])  + E(a[3])+ .................+E(a[num]))/(num-1)//这里有必要说明一下

约数1的贡献是零(概率是1/(num-1)),另外还有就是E(a[num]) = tmp,就是x有几个约数,因为从x到约数需要一步

num个约数的话就要num步;

#include <bits/stdc++.h>
using namespace std;
const int Max = 1e5+100;
const int inf = 0x3f3f3f3f;
typedef long long ll;
#define rep(i,s,n) for( int i=s;i<=n;i++)
#define per(i,n,s) for( int i=n;i>=s;i--)
int t,tmp;
double dp[Max];
void pri(){
     dp[1]=0.0,dp[2]=2.0;
     rep(i,3,Max-10){
         tmp=0;
         double sum=0;
         rep(j,1,sqrt(i)){
             if(i%j!=0)  continue;
             sum+=dp[j], tmp++;
             if(i/j!=j)  sum+=dp[i/j],tmp++;
         }
         sum+=tmp;//表示的是从i到这个约数要除一次每一个约数都要除以一次有tmp个约数就要tmp次;
         dp[i]=sum/(tmp-1);//因为1没有任何的贡献;
     }
}
int main(){
  int t;
  pri();
  scanf("%d",&t);
  int ca=1;
  while(t--){
    int n;
    scanf("%d",&n);
    printf("Case %d: %.10lf\n",ca++,dp[n]);
  }
  return 0;
}
 

猜你喜欢

转载自blog.csdn.net/qq_39792342/article/details/82153198
今日推荐