1. 程式人生 > >某考試 T1 fair (18.5.1版)

某考試 T1 fair (18.5.1版)

每天 lin cst -- tdi pre 圖片 sqrt long long

技術分享圖片

轉化一下模型:每天可以選1也可以選0,但是任意前i天(i<=n)1的個數都必須>=0的個數,求總方案數/2^n。

然後可以發現這是一個經典題,隨便推一下公式發現等於 C(n,n/2)/2^n [請在二維平面直角坐標系上自行演算,(x,y)可以到 (x+1,y)和(x,y+1),橫坐標代表1的個數,縱坐標代表0的個數,求不經過 y=x+1 這條直線的路徑總數 (重點是 任意 (x,y) 滿足 x+y==n 且 x>=y)]

本來以為卡卡常數就過去了23333,沒想到竟然還要用 階乘逼近公式!

那就記一下好啦,反正這玩意也根本沒法理解啊qwq

當n很大 的時候,n! 與 sqrt(2*π*n) * (n/e)^n 之間的相對誤差非常小(然鵝?),所以可以近似成相等啦

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#define ll long long
#define D double
using namespace std;
const D pi=acos(-1),E=exp(1);
D now=1,ans=1,B=log(4);
int n,hf;

inline void solve(){
	hf=n>>1;
	if(n&1){ ans=n/(D)(n-hf)/2,n--;}
	
	ans=log(ans);
	for(int i=hf+1;i<=n;i++) ans+=log(i)-log(i-hf)-B;
	ans=exp(ans);
}

inline D jc(int x){ return log(sqrt(2*pi*x))+x*log(x/E);}

inline void Sim(){
	ans=jc(n)-jc(n>>1)-jc(n-(n>>1))-log(2)*n;
	ans=exp(ans);
}

int main(){
	freopen("fair.in","r",stdin);
	freopen("fair.out","w",stdout);
	
	cin>>n;
	if(n<=1e6) solve();
	else Sim();
	printf("%.11lf\n",ans);
	return 0;
}

  

某考試 T1 fair (18.5.1版)