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和他本身),然后再将结果赋给他本身,直到变成1;
让你求执行次数的期望;
设DP[num]:表示数字num变为1执行次数的期望;
则: dp[num]=(dp[x1]+1)/n+(dp[x2]+1)/n+(dp[x3]+1)/n+...+(dp[xn]+1)/n;(其中xn==num)
则dp[num]=(sigma(1,n-1) xi + n)/(n-1);
参考代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define clr(a,val) memset(a,val,sizeof(a)) 4 const int maxn=1e5+10; 5 int T,n; 6 double dp[maxn]; 7 8 void prework() 9 { 10 clr(dp,0); 11 for(int i=2;i<maxn;++i) 12 { 13 int step=sqrt(i),num=-1; 14 double sum=0; 15 for(int j=1;j<=step;++j) 16 { 17 if(i%j==0) 18 { 19 sum+=dp[j]+1,num++; 20 if(j!=i/j) sum+=dp[i/j]+1,num++; 21 } 22 } 23 dp[i]=sum*1.0/num; 24 } 25 } 26 27 int main() 28 { 29 prework(); 30 scanf("%d",&T); 31 for(int cas=1;cas<=T;++cas) 32 { 33 scanf("%d",&n); 34 printf("Case %d: %.7lf ",cas,dp[n]); 35 } 36 37 return 0; 38 }