题意:给你一个数n,不断的除以它的约数,最终变成1。问变成1的步数的期望是多少。注意:n可以除1变成n。
分析:首先2的期望为什么是2,我想了好久都没想明白,最后虽然算出来了,但我依然不知道为什么是2.
计算的思路和 LightOJ 1027 类似。假设 2 的期望是d,那么 d = 1/2 * 1(1 是 从2直接变为1 的步数的期望) + 1/2 * (d + 1)(从2变成2再变成1 的步数的期望) 那么 d = 2;
同样的方法我们可以计算出来1e5以内所有数的期望。
#include<cstdio>
#include<iostream>
using namespace std;
double a[200000];
int main(){
for(int i = 2; i <= 100000; i++){
int k = 0;
double p = 0;
for(int j = 2 ; j * j <= i; j++){
if(i % j == 0){
p += a[j] + 1;
if(i / j != j) {
p += a[i / j] + 1;
k++;
}
k++;
}
}
a[i] = (double) (p + 2) / (k + 1);
}
int T;
scanf("%d", &T);
for(int kase = 1; kase <= T; kase++){
int n;
scanf("%d", &n);
printf("Case %d: %lf\n", kase, a[n]);
}
return 0;
}