题意: 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.
解析:设dp[x]为x到1的期望步数,p是x的因子个数。
dp[x] = (dp[a1]+dp[a2]+.....+dp[ap])/p + 1
a1 ......ap是x的p个因子。
将n的所有因子按顺序保存在数组中,再按上述方式dp。
[code]:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int inf = 0x3f3f3f3f;
int n,m,a[200];
double dp[200];
double sol(){
int i,j,cnt;
m = 0;
for(i = 1;i*i <= n;i++){
if(n%i==0){
a[m++] = i;
if(i*i!=n) a[m++] = n/i;
}
}
sort(a,a+m);
dp[0] = 0;
for(i = 1;i < m;i++){
//printf("%d ",a[i]);
dp[i] = 0;cnt = 0;
for(j = 0;j < i;j++){
if(a[i]%a[j]==0){
dp[i] += dp[j];
cnt++;
}
}
dp[i]/=cnt;
dp[i]+=1.0*(cnt+1.0)/cnt;
}
//putchar('\n');
return dp[m-1];
}
int main(){
int i,j,t,cas,T;
scanf("%d",&cas);
for(T = 1;T <= cas;T++){
scanf("%d",&n);
printf("Case %d: %.8f\n",T,sol());
}
return 0;
}