Zhou Yu
题目大意:我们有 n n n 滴血, m m m 个花色,每轮操作猜一个花色,猜中花色回一滴血,但血量上限为 n n n ,猜错则扣血,扣到 0 0 0 则游戏结束。现在求游戏结束的期望轮数。
如果我们一开始定义 E i E_i Ei 为当前血量为 i i i ,游戏结束的轮数的话,我们会发现十分难转移状态,式子难以化简,所以我们可以换一个想法,我们设 E i E_i Ei 血量为 i i i 变为 血量为 i − 1 i-1 i−1 的期望轮数。
那么首先我们有
E n = m − 1 m + 1 m ( 1 + E n ) E_n=\frac{m-1}{m}+\frac{1}{m}(1+E_n) En=mm−1+m1(1+En)
解得: E n = m m − 1 E_n=\frac{m}{m-1} En=m−1m
若 i ≠ n i≠n i=n 则有: E i = 1 m ( f i + f i + 1 ) + 1 E_i=\frac{1}{m}(f_i+f_{i+1})+1 Ei=m1(fi+fi+1)+1
则有: E i = m ( m − 1 ) + m ( m − 1 ) 2 + m ( m − 1 ) 3 + . . . + m ( m − 1 ) n − i + 1 E_i=\frac{m}{(m-1)}+\frac{m}{(m-1)^2}+\frac{m}{(m-1)^3}+...+\frac{m}{(m-1)^{n-i+1}} Ei=(m−1)m+(m−1)2m+(m−1)3m+...+(m−1)n−i+1m
我们设 q = 1 m − 1 q=\frac{1}{m-1} q=m−11
实际上
E
i
E_i
Ei 也就是一个等比数列的和,我们得其通项为:
a
i
=
m
∗
q
−
q
n
+
1
1
−
q
a_i=m*\frac{q-q^{n+1}}{1-q}
ai=m∗1−qq−qn+1
注意这里的我们用
n
−
i
n-i
n−i 的项替换了
i
i
i 的项,或者直接感性理解可以推出这个通项。
那么我们要求的答案实际上就是: ∑ i = 1 n a i \sum\limits_{i=1}^na_i i=1∑nai
那么实际上求 a i a_i ai 的前 n n n 项和也就是再求一个等差和等比的通项。
最终我们就可以推出答案为:
a
n
s
=
m
×
n
×
q
−
q
2
×
(
1
−
q
n
)
1
−
q
1
−
q
ans= m×\frac{n×q-\frac{q^2×(1-q^n)}{1-q}}{1-q}
ans=m×1−qn×q−1−qq2×(1−qn)
注意特判 m = 2 m=2 m=2 的情况:
a n s = n × ( n + 1 ) ans= n×(n+1) ans=n×(n+1)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int n, m;
double q;
double ksm(double base, int n) {
double ans = 1;
while(n) {
if (n & 1) ans = ans * base;
base = base * base;
n >>= 1;
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
while(~scanf("%d%d", &n, &m)) {
if (m == 2) {
double ans = (1ll + n) * n;
printf("%.8f\n", ans);
continue;
}
q = 1.0 / (m - 1);
double tmp1, tmp2, tmp3, ans;
tmp1 = n * q;
tmp2 = q * q * (1 - ksm(q, n)) / (1 - q);
tmp3 = 1 - q;
ans = (tmp1 - tmp2) / tmp3;
printf("%.8f\n", m * ans);
}
}