1038 - Race to 1 Again
Time Limit: 2 second(s) Memory Limit: 32 MB
Rimi learned a new thing about integers, which is - any positive integer greater than 111 can be divided by its divisors. So, he is now playing with this property. He selects a number NNN. And he calls this DDD.
In each turn he randomly chooses a divisor of DDD (111 to DDD). Then he divides DDD by the number to obtain new DDD. He repeats this procedure until DDD becomes 111. What is the expected number of moves required for NNN to become 111.
Input
Input starts with an integer T(≤10000)T (\leq 10000)T(≤10000), denoting the number of test cases.
Each case begins with an integer N(1≤N≤105)N (1 \leq N \leq 10^5)N(1≤N≤105).
Output
For each case of input you have to print the case number and the expected value. Errors less than 10−610^{-6}10−6 will be ignored.
Sample Input
3
1
2
50
Case 1: 0
Case 2: 2.00
Case 3: 3.0333333333
题意
- 给你一个整数,每次操作可以选一个nnn的正因子并除以这个因子,求这个数第一次变成111的期望操作数
解法
- 计dp[i]dp[i]dp[i]表示n=in=in=i时对应的答案
- 我们知道,期望是试验中每次可能结果的概率乘以其结果的总和,对应于本题中,dp[i]=∑所有使i变成1的操作方案选择此方案对应的概率×此方案的操作数dp[i]=\sum^{所有使i变成1的操作方案}{选择此方案对应的概率\times此方案的操作数}dp[i]=∑所有使i变成1的操作方案选择此方案对应的概率×此方案的操作数
- 首先说明dp[2]=2dp[2]=2dp[2]=2分以下情况讨论
- 第一步选择2的因子222,那么nnn直接变成111,结束操作,这种方案对期望的贡献是T1=12×1T_1=\frac{1}{2}\times 1T1=21×1
- 第一步选择因子111,那么如果后面继续选择111,nnn是保持222不变的,直到选择222,那么显然这种方案下对应的方案是无穷多种的,其贡献
T2=limn→∞(12)1×12×2+(12)2×12×3+...+(12)n×12×(n+1)T22=limn→∞(12)2×12×2+(12)3×12×3+...+(12)n+1×12×(n+1)相减,得T22=limn→∞(12)1×12×2+(12)2×12+...+(12)n×12−(12)n+1×12×(n+1)=12+limn→∞(12)2×12+...+(12)n×12=12+limn→∞12×14×(1−(12)n−1)1−12=0.75T2=1.5\begin{aligned}T_2 &= \lim_{n\rightarrow \infty}^{}{\left(\frac{1}{2}\right)^1\times\frac{1}{2}\times2+\left(\frac{1}{2}\right)^2\times\frac{1}{2}\times3+...+\left(\frac{1}{2} \right)^n\times\frac{1}{2}\times (n+1)} \\ \frac{T_2}{2} &= \lim_{n\rightarrow \infty}^{}{\left(\frac{1}{2}\right)^2\times\frac{1}{2}\times2+\left(\frac{1}{2}\right)^3\times\frac{1}{2}\times3+...+\left(\frac{1}{2} \right)^{n+1}\times\frac{1}{2}\times (n+1)} \\ 相减,得 \\ \frac{T_2}{2}&=\lim_{n\rightarrow \infty} \left(\frac{1}{2}\right)^1\times\frac{1}{2}\times2+ \left(\frac{1}{2}\right)^2\times\frac{1}{2}+...+ \left(\frac{1}{2}\right)^n\times\frac{1}{2}-\left(\frac{1}{2} \right)^{n+1}\times\frac{1}{2}\times (n+1) \\ &=\frac{1}{2}+\lim_{n\rightarrow \infty} \left(\frac{1}{2}\right)^2\times\frac{1}{2}+...+ \left(\frac{1}{2}\right)^n\times\frac{1}{2}\\ &=\frac{1}{2}+\lim_{n\rightarrow \infty} \frac{1}{2}\times \frac{\frac{1}{4}\times(1-(\frac{1}{2})^{n-1})}{1-\frac{1}{2}}\\ &=0.75\\ T_2&=1.5 \end{aligned}T22T2相减,得2T2T2=n→∞lim(21)1×21×2+(21)2×21×3+...+(21)n×21×(n+1)=n→∞lim(21)2×21×2+(21)3×21×3+...+(21)n+1×21×(n+1)=n→∞lim(21)1×21×2+(21)2×21+...+(21)n×21−(21)n+1×21×(n+1)=21+n→∞lim(21)2×21+...+(21)n×21=21+n→∞lim21×1−2141×(1−(21)n−1)=0.75=1.5 - 所以dp[2]=T1+T2=2dp[2]=T_1+T_2=2dp[2]=T1+T2=2
- 然后就可以在可以递推了
- 定义num[i]num[i]num[i]表示iii的因子个数,fac[i][j]fac[i][j]fac[i][j]表示iii的第jjj个因子
dp[i]=∑j=1num[i]1num[i]×(dp[fac[i][j]]+1)dp[i]=\sum_{j=1}^{num[i]}{\frac{1}{num[i]}\times(dp[fac[i][j]]+1)}dp[i]=j=1∑num[i]num[i]1×(dp[fac[i][j]]+1)
需要注意由于计算dp[i]dp[i]dp[i]的时候需要用到dp[i]dp[i]dp[i],而dp[i]dp[i]dp[i]未求出,可以把右边的包含因子iii的项移到左边,然后再计算dp[i]dp[i]dp[i],相当于解一个一元一次方程
- 定义num[i]num[i]num[i]表示iii的因子个数,fac[i][j]fac[i][j]fac[i][j]表示iii的第jjj个因子
- 首先说明dp[2]=2dp[2]=2dp[2]=2分以下情况讨论
附代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
double dp[maxn];
int main()
{
dp[1]=0,dp[2]=2.0;
for(int i=3;i<maxn;i++){
int num=0;
for(int j=1;j*j<=i;j++){
if(i%j==0){
num++;
if(j*j!=i) num++;
}
}
dp[i]=num*1.0/(num-1);
for(int j=1;j*j<=i;j++){
if(i%j==0){
dp[i]+=dp[j]/(num-1);
if(j!=1&&j*j!=i) dp[i]+=dp[i/j]/(num-1);
}
}
}
int t;scanf("%d",&t);
for(int i=1,n;i<=t;i++){
scanf("%d",&n);
printf("Case %d: %.10lf\n",i,dp[n]);
}
}