一眼看上去就是期望 DP,然而蒟蒻不会,在同机房神仙讲解下豁然开朗,于是写篇题解。
Solution
直接设期望买完的钱数不很好搞,因为每次买邮票所需的钱数是随购买次数变化的,所以我们绕个路
设 表示已经买到 种邮票,若要买完剩下的邮票还需买多少次,转移如下:
初始状态是 , 含义是你有 的概率买到已经买到的 种邮票之一,状态仍然是 , 含义是你有 的概率买到还没买到的 种邮票之一,状态是 ,最后在加上这次买的一次贡献。
再设 表示已经买到 种邮票,若要买完剩下的邮票还需买多少钱,转移如下:
初始状态是 ,仍然很好想。那 是什么意思呢?放图镇楼:

里面加的那个 其实就是给后面的每一次购买都+1,因为当你这次购买后,比如后面的某次是原来是第 次,现在就是第 次,价格+1,那么后面有几次购买呢?就是 次,最后别忘了你这第 次也要+1。 同理。
最后,把 移项化简一下就好了:
Talk is cheap, show me your code:
#include <cstdio>
const int N = 10005;
int n;
double f[N], g[N];
int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
freopen("testdata.in", "r", stdin);
freopen("testdata.out", "w", stdout);
#endif
#ifndef LOCAL
freopen("CppTest.in", "r", stdin);
freopen("CppTest.out", "w", stdout);
#endif
#endif
scanf("%d", &n);
for (int i = n - 1; ~i; --i) {
f[i] = f[i + 1] + 1.0 * n / (n - i);
}
for (int i = n - 1; ~i; --i) {
g[i] = 1.0 * i / (n - i) * f[i] + g[i + 1] + f[i + 1] + 1.0 * n / (n - i);
}
printf("%.2lf", g[0]);
return 0;
}