【题意】
给出一个数大于1的N,每次除以任意的一个他的因子,直到变为1,问从N除到1的次数的期望。
【思路】
递推,设该数为D,有N个因子,分别是1,n1,n2,n3…nn-2,D,
那么选到每个因子的概率都是1/N,除非选到D,不然选到其他因子的话都要多1步,然后再计算D除以该因子的期望
这就能得到公式了,设dp[D]为数D按规则变成1的期望步数
那么dp[D] = 1/N * (dp[D/1] + 1) + 1 / N * (dp[D/n1] + 1) + 1/ N * (dp[D/n2] + 1) + … + 1/N * (dp[D/nn-2] + 1) + 1/N * (dp[D / D] + 1)
化简得 dp[D] = 1 / (N-1) * (dp[D/n1] + dp[D/n2] + … + dp[D/nn-2] + N)。
还有,cout输出的double精度和printf输出的精度有区别。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <ctype.h>
#include <cstring>
#include <cstdio>
#include <sstream>
#include <cstdlib>
#include <iomanip>
#include <string>
#include <queue>
#include <map>
using namespace std;
double dp[100000+10];
int main()
{
dp[1]=0;
dp[2]=2;
for(int i=3;i<=100000;i++)
{
dp[i]=0;
int num=0;
for(int j=1;j*j<=i;j++)
{
if(i%j==0)
{
num++;
dp[i]+=dp[j];
if(i/j!=j)
{
num++;
dp[i]+=dp[i/j];
}
}
}
dp[i]=(dp[i]+num)/(num-1);
}
int T,cases=1;
cin>>T;
while(T--)
{
int n;
cin>>n;
printf("Case %d: %lf\n",cases++,dp[n]);
}
}