UVA557 汉堡Burger(数学+组合)

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

先把 n / = 2 n/=2

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

然而这个是不对的。
十分的 n a i v e naive

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

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

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

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

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

a n s = 1 C 2 n 2 n 1 2 2 n 2 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\n",ans);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/y752742355/article/details/85158338