题目:https://vjudge.net/contest/277062#problem/C
题意:每次可以变成n除以任意它的除数,问最后变成1需要多少次期望。
暴力求所有除数dp 一下即可。
ac代码
#include <cstdio>
#include <cstring>
#include <vector>
#include <iterator>
#include <set>
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
const double esp = 1e-6;
const int mx = 2e5+100;
set<int>ve[mx];
double dp[mx];
void init(int n) {
for (int i = 1; i <= sqrt(n); ++i) {
if (n%i == 0) {
ve[n].insert(i);
if (ve[i].size() == 0) init(i);
ve[n].insert(n/i);
if (ve[n/i].size() == 0) init(n/i);
}
}
if (ve[n].size() == 2) dp[n] = 2;
return;
}
void dfs(int n) {
double sum = 0;
if (dp[n] > esp || n == 1) return;
for (set<int>::iterator i = ve[n].begin(); i != ve[n].end(); ++i) {
int v = *i;
if (v == n) continue;
dfs(v);
sum+=dp[v];
}
dp[n] = (sum + ve[n].size())/(ve[n].size()-1);
}
int main() {
int q, o = 1, n;
ve[1].insert(1);
for (scanf("%d", &q); o <= q; ++o) {
printf("Case %d: ", o);
scanf("%d", &n);
if (ve[n].size() == 0)
init(n);
dfs(n);
printf("%f\n", dp[n]);
}
return 0;
}