Beating the Dataset LightOJ - 1274
有 n n n 个文件,每个文件里面包含 Y E S YES YES 或者 N O NO NO,前者 3 bytes,后者 2 bytes,并且知道这些文件的总大小 s s s。
现在定义自己的输出,第 1 1 1 个输出为 Y E S YES YES,第 i ( 2 ≤ i ≤ n ) i(2\le i\le n) i(2≤i≤n) 个输出为第 i − 1 i-1 i−1 个文件中包含的内容,也就是说,假如 n n n 个文件中分别包含字符串为 x 1 , ⋯ , x n x_1,\cdots, x_n x1,⋯,xn,那么自己的输出就是 x 0 , x 1 , ⋯ , x n − 1 x_0,x_1,\cdots,x_{n-1} x0,x1,⋯,xn−1,其中 x 0 x_0 x0 为 Y E S YES YES。
问自己的输出和给定的文件平均会有多少个不一样?
我觉得这道题还是挺难的…
首先根据 s s s 和 n n n 就可以分别计算出 Y E S YES YES 和 N O NO NO 的个数,问题就可以转化为 x x x 个 0 0 0 和 y y y 个 1 1 1 组成一个 01 01 01 串,问这个串的全排列其中一个位置与前一个位置不同或者第一位为 0 0 0 的期望。
首先认为这些 0 , 1 0,1 0,1 是互异的,那么总的方案数有 ( x + y ) ! (x+y)! (x+y)! 种,把 01 01 01 看成一个数字,形成的排列个数有 ( x + y − 1 ) ! (x+y-1)! (x+y−1)! 种,而 01 01 01 本身又有 x ⋅ y x\cdot y x⋅y 种, 01 01 01 可以交换变成 10 10 10,那么相当于有 2 x y 2xy 2xy 种;把 0 0 0 放在首位有 x x x 种,后面随便排列,有 ( x + y − 1 ) (x+y-1) (x+y−1) 种,因此期望为:
( 2 x y ⋅ ( x + y − 1 ) ! + x ⋅ ( x + y − 1 ) ! ) ( x + y ) ! = 2 x y + x x + y \frac{(2xy\cdot(x+y-1)!+x\cdot(x+y-1)!)}{(x+y)!}=\frac{2xy+x}{x+y} (x+y)!(2xy⋅(x+y−1)!+x⋅(x+y−1)!)=x+y2xy+x
代码如下:
#include<iostream>
#include<cstdio>
//#define WINE
using namespace std;
int T,iCase,n,s,x,y;
int main(){
#ifdef WINE
freopen("data.in","r",stdin);
#endif
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&s);
y=s-2*n;x=n-y;
printf("Case %d: %.8lf\n",++iCase,(2.0*x*y+x)/n);
}
return 0;
}