P4550 收集邮票
https://lightoj.com/problem/dice-iii的加强版本。设
c
[
i
]
c[i]
c[i] 为现已经收集了
i
−
1
i-1
i−1 种邮票,要搜集到第
i
i
i 种邮票的花钱次数期望,
s
u
m
c
[
i
]
sumc[i]
sumc[i] 为
c
[
i
]
c[i]
c[i] 的前缀和,
E
[
i
]
E[i]
E[i] 为已经收集到
i
−
1
i-1
i−1 种邮票,要收集到第
i
i
i 种邮票需要花的钱的期望。
c
[
i
]
c[i]
c[i] 与
s
u
m
[
i
]
sum[i]
sum[i] 的计算就和这题一样https://lightoj.com/problem/dice-iii
那么现在有:
E
[
i
]
=
(
s
u
m
c
[
i
−
1
]
+
1
)
+
i
−
1
n
(
E
[
i
]
+
c
[
i
]
)
E[i]=(sumc[i-1] + 1)+\frac{i-1}{n}(E[i]+c[i])
E[i]=(sumc[i−1]+1)+ni−1(E[i]+c[i])
这么理解:首先肯定得买一次,那么这一次的代价就得看当前已经买了多少次,那么自然已经买了
s
u
m
c
[
i
−
1
]
sumc[i-1]
sumc[i−1] 次,现在再买就要付
(
s
u
m
c
[
i
−
1
]
+
1
)
(sumc[i-1]+1)
(sumc[i−1]+1) 块钱。然后如果我们买到了前面出现过的邮票自然就要继续买,这样的概率显然是
i
−
1
n
\frac{i-1}{n}
ni−1 ,那么现在只要考虑后面还要花多少钱,和
E
[
i
]
E[i]
E[i] 相比,现在一开始我就要付
(
s
u
m
c
[
i
−
1
]
+
2
)
(sumc[i-1]+2)
(sumc[i−1]+2) ,一开始就多付一块钱,那么我会买
c
[
i
]
c[i]
c[i] 次,那么最后我就会多付
c
[
i
]
c[i]
c[i] 块,所以此时我要花
E
[
i
]
+
c
[
i
]
E[i]+c[i]
E[i]+c[i] 。所以最终解得
E
[
i
]
E[i]
E[i] ,
∑
i
=
1
n
E
[
i
]
\sum\limits_{i=1}^nE[i]
i=1∑nE[i] 即是答案。
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
double c[N], sumc[N], E[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
c[i] = 1.0 * n / (n - i + 1);
sumc[i] = sumc[i - 1] + c[i];
}
double ans = 0;
for (int i = 1; i <= n; ++i) {
ans += (sumc[i - 1] + 1) * n / (n - i + 1) + c[i] * (i - 1) / (n - i + 1);
}
printf("%.2f", ans);
}