题解:
把每个球的操作一次后的期望具体写出来,发现还是一个等差数列,猜个结论:把之后的局面用这个等差数列算是等价的(其实应该也不难理解)。
假设现在等差数列为
(
d
,
x
)
(d,x)
(d,x),我们可以发现:
操作一次后:
d
′
=
(
(
2
n
−
2
)
d
+
(
d
+
x
)
+
(
3
d
+
3
x
)
)
2
n
d'=\frac{((2n-2)d+(d+x)+(3d+3x))}{2n}
d′=2n((2n−2)d+(d+x)+(3d+3x)) (其实就是1距离左边的期望距离)
s u m ′ = s u m − ( d + ( d + x ) + ( ( 2 n − 2 ) x + d ) + ( ( 2 n − 1 ) x + d ) ) 2 n sum'=sum-\frac{(d+(d+x)+((2n-2)x+d)+((2n-1)x+d))}{2n} sum′=sum−2n(d+(d+x)+((2n−2)x+d)+((2n−1)x+d)) (只有两种操作会引起和的改变)
根据 s u m ′ sum' sum′和 d ′ d' d′就可以轻松的算出 x ′ x' x′了,递归到长度为1即可,时间复杂度 O ( n ) O(n) O(n)。
#include <bits/stdc++.h>
using namespace std;
typedef long double DB;
DB d,x,n;
int main() {
cin>>n>>d>>x; DB ans=0;
for(int i=n;i>=1;i--) {
DB sum=(d*2*n+n*(2*n-1)*x);
ans+=sum/2/n;
DB d2=(d*(2*n-2)+d+2*x+3*d+3*x)/2/n;
sum=sum-(4*d+4*n*x-2*x)/2/n;
n-=1;
DB x2=(sum-2*n*d2)/n/(2*n-1);
d=d2; x=x2;
} printf("%.15f\n",(double)ans);
}