题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=25915
题意:给一个数n,每次等概率选择它的一个因子p,然后得到n/p,求变为1时的期望次数。
思路:f[i]表示从i变为1的期望次数,f[i] = 1/t ( ∑f[j] ) + 1 ( j是i的因数 )化简一下,得到 f[i] = ( ( ∑f[j] ) + t ) / ( t-1 ) //t为所有的因子个数,包括1和本身 j为i的真因子。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
#define Clean(x,y) memset(x,y,sizeof(x))
const int maxn = 100009;
double f[maxn];
bool flag[maxn];
int p[maxn][10];
int n,T;
void getfactor(int x)
{
p[x][0] = 0;
for( int i = 2; i * i <= x; i++ )
{
if ( x % i == 0 )
{
p[x][ ++p[x][0] ] = i;
if ( i * i != x )
p[x][ ++p[x][0] ] = x / i;
}
}
}
double cal( int x )
{
if ( flag[x] ) return f[x];
flag[x] = true;
getfactor(x);
double ans = 0;
for(int i = 1; i <= p[x][0]; i++) ans+=cal( x / p[x][i] );
return f[x] = ( ans + p[x][0] + 2 ) / ( p[x][0] + 1 );
}
int main()
{
Clean(flag,false);
f[0] = f[1] = 0;
flag[0] = flag[1] = true;
Clean(p,0);
scanf("%d",&T);
int k = 0;
while(T--)
{
k++;
scanf("%d",&n);
printf("Case %d: %.10f\n",k,cal(n));
}
return 0;
}