这题我会!
C
2
n
n
2
C
2
n
−
2
n
\frak{\dfrac{C^n_{2n}}{2C^{n}_{2n-2}}}
2C2n−2nC2nn!个鬼
上面做法的前提是每一种组合出现的概率完全一致。
但是这道题目它
显然不是的吧?
重点就在于,每一种的个数是有限制的
就是,可能到某个位置,就再也不用考虑某一种票:因为这种票没了。
所以要按位置递推。
有两种想法,第一种是f(i,j)表示位置i放了j个某种票,
第二种是表示某个位置放了i个某种票、j个另一种票。
我比较鶸,思维氵化了,根本没有想到第二种(
第一种
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
int n, fn;
double f[1255][648];
int main() {
scanf("%d",&n);
fn = n >> 1;
f[1][0] = f[1][1] = 0.5;
for (int i = 1; i < n; ++i) {
for (int j = 0; j <= i; ++j) {
int k = i - j;
if (k > fn) continue;
if (j > fn) continue;
if (j == fn) {
f[i+1][j] += f[i][j];
}
else if (k == fn) {
f[i+1][j+1] += f[i][j];
}
else f[i+1][j+1] += f[i][j] * 0.5,
f[i+1][j] += f[i][j] * 0.5;
}
}
printf("%.4f", 2 * f[n-2][fn]);
return 0;
}
第二种
按照“有多少个A,B的时候,
假如最后一个选了A/B,
倒数第二个和最后一个选的票种类相同”的概率来转移。
可能这就是大佬吧
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
int n, fn;
double f[1255][648];
int main() {
scanf("%d",&n);
fn = n >> 1;
f[1][0] = f[1][1] = 0.5;
for (int i = 1; i < n; ++i) {
for (int j = 0; j <= i; ++j) {
int k = i - j;
if (k > fn) continue;
if (j > fn) continue;
if (j == fn) {
f[i+1][j] += f[i][j];
}
else if (k == fn) {
f[i+1][j+1] += f[i][j];
}
else f[i+1][j+1] += f[i][j] * 0.5,
f[i+1][j] += f[i][j] * 0.5;
}
}
printf("%.4f", 2 * f[n-2][fn]);
return 0;
}
概率真的没怎么做过也不怎么会做,被吊打了。。