「Codeforces 335E」Counting Skyscrapers

传送门


problem

在一条公路上,有一排摩天大楼,数量在 2 ∼ 314 ! 2\sim 314! 2314! 之间。每一栋大楼有一个高度(正整数),高度为 i i i 的概率为 2 − i 2^{-i} 2i

为了出题某种特殊原因,在大楼之间安装了一些溜索,且在某栋楼的i层和另一栋楼的i层之间有一条溜索,当且仅当这两栋楼之间没有一栋大楼高度达到 i i i 层。 AliceBob 决定数一数摩天大楼的数量。

Alice 非常细心,她从最左侧的摩天大楼出发,计数器为 1 1 1。然后她向右移动,每次移到下一栋大楼,都将计数器加 1 1 1。她一直走到最右侧的大楼。(就是有多少栋数出来多少栋)。

Bob 非常没耐心,他希望尽快数完。他从最左侧的摩天大楼开始,计数器为 1 1 1。他使用溜索在大楼之间移动。每次 Bob 都用最高的溜索向右移动,但由于恐高,他会忽略掉那些编号超过 h h h 的楼层。Bob 用溜索旅行跑得比香港记者还快,以至于他根本没法数清经过了多少大楼。因此他只是将计数器加上 2 i 2^i 2i,其中 i i i 是他当前所在的楼层编号。他持续移动,直到到达最右侧的大楼。(注意编号从 0 0 0 开始)。

举个例子。有 6 6 6 栋大楼,从左到右的高度分别是 1 , 4 , 3 , 4 , 1 , 2 1,4,3,4,1,2 1,4,3,4,1,2,且 h = 2 h=2 h=2Alice 开始时计数器为 1 1 1,并且将计数器加了五次 1 1 1,得到的结果是 6 6 6Bob 开始时计数器为 1 1 1,然后他依次加上 1 , 4 , 4 , 2 1,4,4,2 1,4,4,2,最终得到 12 12 12。注意,Bob 出于恐高忽略掉了最高的溜索。
在这里插入图片描述
AliceBob 到达最右端的大楼时,他们将各自的计数器拿出来比较。给出 Alice 或者 Bob 的计数器的值,你需要计算出另外一个人的计数器的期望值。

数据范围: 2 ≤ n ≤ 30000 2\le n\le30000 2n30000 0 ≤ h ≤ 30 0\le h\le30 0h30


solution

神仙数学题啊 orz。

推导过程看这里吧,我就只写结论了。

  • BobAlice a n s = n ans=n ans=n
  • AliceBob a n s = n + ∑ i = 1 h ∑ j = 1 n ( n − j ) × ( 1 − 1 2 i ) j − 1 × ( 1 2 ) 2 i × ( 2 i − 2 i − 1 × ( 1 + ( j − 1 ) 1 2 i − 1 ) ) ans=n+\sum\limits_{i=1}^h\sum\limits_{j=1}^n(n-j)\times (1-\frac 1{2^i})^{j-1}\times (\frac 1 2)^{2i}\times (2^i-2^{i-1}\times (1+(j-1)\frac 1{2^i-1})) ans=n+i=1hj=1n(nj)×(12i1)j1×(21)2i×(2i2i1×(1+(j1)2i11))

code

#include<bits/stdc++.h>
using namespace std;
char S[10];
double P[35];
double power(double a,int b){
	double ans=1;
	for(;b;b>>=1,a*=a)  if(b&1)  ans*=a;
	return ans;
}
int main(){
	int n,h;
	scanf("%s%d%d",S,&n,&h),P[0]=1;
	for(int i=1;i<=30;++i)  P[i]=P[i-1]*2;
	if(S[0]=='B')  printf("%.9lf\n",(double)n);
	else{
		double ans=n;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=h;++j)
				ans+=(n-i)/P[j]/P[j]*power(1.0-1.0/P[j],i-1)*(P[j]-P[j-1]*(1.0+(i-1)/(P[j]-1)));
		printf("%.9lf\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值