UVA557 汉堡 Burger

真的是一道比较不错的题了呢。qwq

先把(n/=2)

首先一开始第一思路肯定是直接对于每种汉堡,(C^{n}_{2n-2})就是后面两个吃到他的方案,然后直接两个加起来除以(2^{2n})

然而这个是不对的。
十分的(naive)

原因如下:
我们把问题抽象成一个二维平面上的((0,0)->(n,m))的问题。

但如果我们走到了(x=n或者y=m),那么之后另一种的选择的概率就是 1。就相当于概率坍塌了。
也就是说,我们不能把(2^{2n})当成总的方案数了。
那应该怎么算呢?

QWQ
我们考虑用总概率减去不合法的概率。

那么不合法的概率应该是什么呢?就是从((0,0)点走到(n-1,m-1))的概率。这个过程中显然是不会因为边界而导致概率坍塌的。

所以!我们可以直接用组合数算!!!

[ans = 1 - frac{C_{2n-2}^{n-1}}{2^{2n-2}} ]

QWQ但是这个题要注意的事情是卡精度!

所以要用一边算组合数,一边除以2的方法才能避免精度问题

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
using namespace std;
inline int read()
{
  int x=0,f=1;char ch=getchar();
  while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  return x*f;
}
int n,t;
double ans;
double now;
int main()
{
  t=read();
  while (t--)
  {
  	n=read();
  	n/=2;
  	now=1;
  	int ymh = 2*n-2;
  	for (int i=1;i<=n-1;i++)
  	{
  		double ii =i;
  		double iii = i+(n-1);
  		now = now * iii/ii;
  		while (ymh>=1 && now>=1)
  		{
  			now/=2;
  			ymh--;
		}
  		//cout<<now<<endl;
	  }
	while (ymh>=1)
	{
		now/=2;
		ymh--;
	}
	ans=1.0-now;
	printf("%.4lf
",ans);
  }
  return 0;
}

原文地址:https://www.cnblogs.com/yimmortal/p/10154454.html