C - Pushing Balls(数学期望)

https://vjudge.net/problem/AtCoder-agc007_c

题意:

给2n+1个物体,奇数位置为洞,偶数位置为球。 D i s ( i , i + 1 ) = d + ( i − 1 ) x Dis(i,i+1)=d+(i-1)x Dis(i,i+1)=d+(i1)x
现在任意选择一个求往左或右推。会掉到洞里面,其它球就会踩着他滚过去。

问最后所有球滚动的距离之和的期望。

解析:

题目转化为选择任意两个相邻的点,之后删除这两个点。

在这里插入图片描述

初始为 d , d + x , d + 2 x , d + 3 x , d + 4 x . . . d,d+x,d+2x,d+3x,d+4x... d,d+x,d+2x,d+3x,d+4x...,总共2n段

第一次选择获得期望长度为 S ( 2 n ) / 2 n S(2n)/2n S(2n)/2n

我们分析第一次滚动后形成的期望局面(每一段的)

  • 选择点 ( 1 , 2 ) (1,2) (1,2)变为 d + 2 x , d + 3 x , d + 4 x . . . d+2x,d+3x,d+4x... d+2x,d+3x,d+4x...
  • 选择点 ( 2 , 3 ) (2,3) (2,3)变为 3 d + 3 x , d + 3 d , d + 4 x . . . 3d+3x,d+3d,d+4x... 3d+3x,d+3d,d+4x...
  • 选择点 ( 3 , 4 ) (3,4) (3,4)变为 d , d + 6 x , d + 4 x . . . d,d+6x,d+4x... d,d+6x,d+4x...
  • 选择点 ( 4 , 5 ) (4,5) (4,5)变为 d , d + x , d + 9 x . . . d,d+x,d+9x... d,d+x,d+9x...

第一个段的期望:

  • 1 2 n \dfrac{1}{2n} 2n1的概率变为 d + 2 x d+2x d+2x
  • 1 2 n \dfrac{1}{2n} 2n1的概率变为 3 d + 3 x 3d+3x 3d+3x
  • 2 n − 2 2 n \dfrac{2n-2}{2n} 2n2n2的概率变为 d d d
  • 所以期望为: 4 d + 5 x + ( 2 n − 2 ) d 2 n \dfrac{4d+5x+(2n-2)d}{2n} 2n4d+5x+(2n2)d

第二个段的期望:

  • 2 2 n \dfrac{2}{2n} 2n2的概率变为 d + 3 x d+3x d+3x
  • 1 2 n \dfrac{1}{2n} 2n1的概率变为 3 d + 6 x 3d+6x 3d+6x
  • 2 n − 3 2 n \dfrac{2n-3}{2n} 2n2n3的概率变为 d + x d+x d+x
  • 所以期望为: 5 d + 9 x + ( 2 n − 3 ) ( d + x ) 2 n \dfrac{5d+9x+(2n-3)(d+x)}{2n} 2n5d+9x+(2n3)(d+x)

第三段……

分析后得到的期望局面发现也是个等差数列,所以递归做即可。

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-12-05-12.06.34
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define LD long double
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<"> "<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=1e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

LD dfs(int n,LD d,LD x){
    if(n==0)return 0;
    LD sum=(n*d)+((LD)n*(n-1)*x)/2.0;
    return sum/n+dfs(n-2,   d*(n-2)/n + (d+2*x)/n + (3*d+3*x)/n ,
                            (d+x)*(n-3)/n + (d+3*x)*2/n + (3*d+6*x)/n -
                            (d*(n-2)/n + (d+2*x)/n + (3*d+3*x)/n));
}

int main(){
    int n=rd;
    LD d=rd,x=rd;
    printf("%.12f\n",(double)dfs(2*n,d,x));
    return 0;
}

/*_________________________________________________________end*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值