\(f_i\)为从
\(i\)到
\(i+1\)的期望步数。
\(f_i = 1-p + p(f_i + 2((1-q)^{n-i}(n-i) + q\sum_{j=0}^{n-i-1}(1-q)^{j}j))\) 移项相减得:
\(f_i = 1+\frac{2p((1-q)^{n-i}(n-i) + q\sum_{j=0}^{n-i-1}(1-q)^{j}j)}{1-p}\) 然后预处理一个前缀和就可以了。
代码:
#pragma GCC optimize(2)#pragma GCC optimize(3)#pragma GCC optimize(4)#include using namespace std;#define y1 y11#define fi first#define se second#define pi acos(-1.0)#define LL long long//#define mp make_pair#define pb emplace_back#define ls rt<<1, l, m#define rs rt<<1|1, m+1, r#define ULL unsigned LL#define pll pair #define pli pair #define pii pair #define piii pair #define pdd pair #define mem(a, b) memset(a, b, sizeof(a))#define debug(x) cerr << #x << " = " << x << "\n";#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//headconst int N = 1e5 + 10;int n;double p, q, _q[N], sum[N];int main() { while(~scanf("%d %lf %lf", &n, &p, &q)) { sum[0] = 0; _q[0] = 1; for (int i = 1; i <= n; ++i) { _q[i] = _q[i-1]*(1-q); sum[i] = sum[i-1] + _q[i]*i; } double ans = 0; for (int i = 0; i < n; ++i) { ans += 1+(2*p*(_q[n-i]*(n-i)+q*sum[n-i-1]))/(1-p); } printf("%.10f\n", ans); } return 0;}