[AGC007C]Pushing Balls

280 篇文章 1 订阅

题目

传送门 to AtCoder

思路

这是一道人类智慧题;果然我不配做人!

n a i v e \rm naive naive 的想法是 O ( n 2 ) \mathcal O(n^2) O(n2) d p \tt dp dp 求出每一个小段的期望经过次数。没找到优化点。

我们是不是应该考虑一下 距离是等差 这个别有用心的设计?——没错,就是 “别有用心” 而不是 “别具匠心”。

本来 d p \tt dp dp 就是递归子问题,但是它更彻底。设原距离数组是 a x = d x + b a_x=dx{+}b ax=dx+b,考虑进行一次操作后,剩下的长度为 ( 2 n − 2 ) (2n{\rm -}2) (2n2) 的距离数组的每一项的 期望值(就是概率乘长度的和嘛,相当于在递归中的贡献系数)。

为了方便,可以忽略 “球” 和 “洞” 的身份,笼统说为 “相邻元素可同时删去”。那么,对于第 x    ( 1 ⩽ x ⩽ 2 n − 2 ) x\;(1\leqslant x\leqslant 2n{-}2) x(1x2n2) 项,若删去前面 a y    ( 1 ⩽ y ⩽ x ) a_y\;(1\leqslant y\leqslant x) ay(1yx) 的左右端点,则 a y a_y ay 会再拓展 2 2 2 个区间,使得 a x ′ = a x + 2 a'_x=a_{x+2} ax=ax+2(顺次补齐两个空洞)。概率是 x 2 n x\over 2n 2nx

若删去 a x + 1 a_{x+1} ax+1 的左右端点则 a x ′ = a x + a x + 1 + a x + 2 a'_x=a_x+a_{x+1}+a_{x+2} ax=ax+ax+1+ax+2,概率是 1 2 n 1\over 2n 2n1 。其他情况下 a x ′ = a x a'_x=a_x ax=ax,概率是 2 n − x − 1 2 n {2n-x-1\over 2n} 2n2nx1 。三者相加,得到新期望长度
a x ′ = x a x + 2 + 3 a x + 1 + ( 2 n − x − 1 ) a x 2 n = ( 2 n − 1 ) a x + 2 d x + 3 a x + 1 2 n \begin{aligned} a'_x &=\frac{xa_{x+2}+3a_{x+1}+(2n{-}x{-}1)a_x}{2n}\\[1ex] &=\frac{(2n{-}1)a_x+2dx+3a_{x+1}}{2n} \end{aligned} ax=2nxax+2+3ax+1+(2nx1)ax=2n(2n1)ax+2dx+3ax+1

于是 a x ′ − a x − 1 ′ = ( 2 n − 1 ) d + 2 d + 3 d 2 n = n + 2 n d a'_{x}-a'_{x-1}=\frac{(2n-1)d+2d+3d}{2n}=\frac{n+2}{n}d axax1=2n(2n1)d+2d+3d=nn+2d 为常数。新的期望距离仍然是等差数列

所以,我们递归到一个 a x = n + 2 n d x + b ′ a_x=\frac{n+2}{n}dx+b' ax=nn+2dx+b 的情况,仍然可以用上面的方法计算。现在只需要快速求出第一次操作提供的贡献。

第一次操作时,每个距离都可以被等概率选中;期望应为 ∑ a i 2 n = a 1 + a 2 n 2 \frac{\sum a_i}{2n}={a_1+a_{2n}\over 2} 2nai=2a1+a2n,等差数列的平均值嘛。每次 O ( 1 ) \mathcal O(1) O(1),时间复杂度就 O ( n ) \mathcal O(n) O(n) 了。

代码

极度舒适的代码 😎

#include <cstdio>
int main(){
	int n; double ans, head, d;
	scanf("%d %lf %lf",&n,&head,&d);
	for(ans=0; n; d=d*(n+2)/n,--n){
		ans += head+((n<<1)-1)*d/2;
		head += (2*head+5*d)/(n<<1);
	}
	printf("%.12f\n",ans);
	return 0;
}
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值