zoukankan      html  css  js  c++  java
  • Agc007_C Pushing Balls

    传送门

    题目大意

    在一条直线上有$N$个球和$N+1$个洞,每两个球之间有一个洞,每两个洞之间有一个球,最左端和最右端都是洞,其中产生的$2N$个间隔满足从左到右是等差数列。你每次随机选择一个未被推进洞的球,将它随机向左或向右推动直到遇见一个洞,这时求会滚进洞内填满这个洞,接下来的球会正常从这个洞上方经过,显而易见不会有球撞到球或走出边界的情况,求所有任一方案所有球移动距离的期望。

    题解

    人类智慧题

    将题目转化为有$2N$个区间,每次可以拿走$2$个相邻的端点并获得端点距离的贡献

    考虑移动一次后剩下的$2N-2$个区间,单独考虑每一个区间,假设第$1$个区间,设首项为$X$,公差为$K$。

    若我们拿走$2N$个区间中的第$1$个,则第一个区间会从$X$增加为$X+2K$,即长度变成了原序列中的第$3$个区间。

    若我们拿走$2N$个区间中的第$2$个,则第一个区间会从$X$增加为$3X+3K$,即长度变成了原序列中的前$3$个区间。

    其余情况第一个区间不变,则第一个区间期望增加$frac{2X+5K}{2N}$。

    同理,发现每个区间变化的期望会形成一个等差数列,那么$2N-2$个区间仍然能构成一个等差数列。

    我们只要不断维护这一等差数列,维护首项末项公差,每次对答案的贡献是首项与末项的平均数。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define DB double
    #define M 400020
    using namespace std;
    int read(){
    	int nm=0,fh=1; char cw=getchar();
    	for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
    	for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
    	return nm*fh;
    }
    LL n,tot,d[M];
    DB ans,fs,ed,k,dt;
    int main(){
    	n=read(),fs=read(),k=read();
    	ed=fs+k*(n*2-1);
    	for(int i=(n<<1);i;i-=2){
    		ans+=((fs+ed)/2.0);
    		fs+=(fs*2+k*5)/(i*1.0); dt;
    		ed+=dt=(ed*2-k*5)/(i*1.0); dt;
    		if(i>2) k=(ed-fs)/((i-2)*1.0-1.0);
    	}
    	printf("%.17lf
    ",ans);
    	return 0;
    }
  • 相关阅读:
    【Vue教程系列:第一篇】Win7 搭建Vue开发环境
    MVC 之 WebAPI 系列二
    MVC 之 WebAPI 系列一
    Javascript 截取2位小数
    Javascript 处理时间大全
    SpringBoot是如何动起来的?
    超全、超详的Spring Boot配置讲解笔记
    Java数据结构-ArrayList最细致的解析笔记
    Redis 到底是怎么实现“附近的人”这个功能的?
    02--Java Jshell的使用 最适合入门的Java教程
  • 原文地址:https://www.cnblogs.com/OYJason/p/9860129.html
Copyright © 2011-2022 走看看