loj 1038(dp求期望)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25915
题意:求一个数不断地除以他的因子,直到变成1的时候 除的次数的期望。
思路:设一个数的约数有num个,E[n] = (E[a[1]]+1)/num+(E[a[2]]+1)/num+...+(E[a[num]]+1)/num+1 ,而a[num]==n,于是整理得:
E[n]=(E[a[1]]+E[a[2]]+...+E[a[num-1]]+num)/(num-1)。
然后预处理出所有的结果。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 8 int n; 9 double dp[111111]; 10 11 void Get_Dp() 12 { 13 dp[1]=0; 14 for(int i=2;i<=100000;i++){ 15 int cnt=0; 16 double sum=0; 17 for(int j=1;j*j<=i;j++){ 18 if(i%j==0){ 19 cnt++; 20 sum+=dp[j]; 21 if(j*j!=i){ 22 cnt++; 23 sum+=dp[i/j]; 24 } 25 } 26 } 27 dp[i]=(sum+cnt)/(cnt-1); 28 } 29 } 30 31 int main() 32 { 33 Get_Dp(); 34 int _case,t=1; 35 scanf("%d",&_case); 36 while(_case--){ 37 scanf("%d",&n); 38 printf("Case %d: %.10f\n",t++,dp[n]); 39 } 40 return 0; 41 }