所以再次记录 g[i] 表示当前已经收集了 i 张邮票的情况下,将 n 张邮票全部收集的期望购买次数
显然 g[n]=0
当 0≤i<n 时,有
g[i]=1+nig[i]+nn−ig[i+1]
解方程得
g[i]=n−in+g[i+1]
而 f[i] 表示当前已经收集了 i 张邮票,并且下一次购买邮票的费用为 1 的情况下,将 n 张邮票全部收集的期望费用
分析下转移:如果当前已经收集了 i 张邮票,并且现在又用 1 的费用购买了一张邮票
那么之后所有邮票的费用都加一
而期望情况下之后需要再收集 g[i] (或 g[i+1] )张邮票
所以相当于之后多了 g[i] (或 g[i+1] )的额外费用
于是
f[i]=1+ni(f[i]+g[i])+nn−i(f[i+1]+g[i+1])
解方程得
f[i]=n−in+n−iig[i]+g[i+1]+f[i+1]
最后答案 f[0]
复杂度 O(n)
Code
#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define Rof(i, a, b) for (i = a; i >= b; i--)constint N =1e4+5;int n;double f[N], g[N];intmain(){int i;
std::cin >> n;
Rof (i, n -1,0){
g[i]= g[i +1]+1.0* n /(n - i);
f[i]=1.0* n /(n - i)+1.0* i /(n - i)* g[i]+ f[i +1]+ g[i +1];}printf("%.2lf\n", f[0]);return0;}