记忆化搜索的方式计算f(x)
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define mem(a) memset(a,0,sizeof(a))
const int maxn = 1000005;
int n;
int primes[maxn],prime_cnt;
int vis[maxn];
int v[maxn];
double f[maxn];
void prime_(){
mem(v);
for(int i=2;i<=(int)sqrt(maxn);i++){
for(int j=i*i;j<=maxn;j+=i)if(!v[j]){
v[j]=1;
}
}
prime_cnt=0;
for(int i=2;i<maxn-4;i++){
if(!v[i])
primes[prime_cnt++]=i;
}
}
double dp(int x){
if(x==1) return 0.0;
if(vis[x]) return f[x];
vis[x] = 1;
double& ans = f[x];
int g=0,p=0;
ans=0;
for(int i=0;i<prime_cnt&&primes[i] <= x;i++){
p++;
if(x%primes[i]==0){
g++;
ans+=dp(x/primes[i]);
}
}
ans = (ans+p)/g;
return ans;
}
int main()
{
// freopen("out.txt","w",stdout);
int t;
scanf("%d\n",&t);
mem(vis);mem(f);
prime_();
int kase=0;
while(t--){
scanf("%d",&n);
double ans = dp(n);
printf("Case %d: %.10lf\n",++kase,ans);
}
return 0;
}原文:http://blog.csdn.net/u013382399/article/details/39056763