我已经能够使用std :: next_permutation(c ++)等解决以下问题, 但我现在正在考虑更普遍,并且非常想形成一个 因为这种类型的问题似乎有助于表达 - 尽管我现在还没有运气。
以下是问题:
鉴于与N名选手的比赛正在进行,准确的M选手将在与他们的球衣上的数字相同的位置完成的概率是多少。 其中M <= N。
到目前为止我做了什么:
会有N!种族可以结束的方式,
我试过摆弄一个由三个或四个参赛者组成的问题的小变种 满足条件的所需人数为2.在两种情况下按特定顺序完成的2人概率为1/2
我想知道是否已经存在某种处理所有情况的表达式?
一些代码:
#include <cstdio>
#include <algorithm>
#include <vector>
int main(int argc, char* argv[]) {
if (argc != 3) return 1;
int n = atoi(argv[1]);
int m = atoi(argv[2]);
if (m > n) return 1;
std::vector<int> lst(n);
for (int i = 0; i < n; ++i) lst[i] = i;
unsigned int total = 0;
unsigned int perm_count = 0;
do {
int cnt = 0;
for (int i = 0; i < n; ++i) if (lst[i] == i) ++cnt;
if (cnt == m)
++total;
++perm_count;
}
while (std::next_permutation(lst.begin(),lst.end()));
printf("Probability of (%d,%d) = %8.7f\n",n,m,(1.0 * total / perm_count));
return 0;
}
更新:该表达式称为部分紊乱:
http://mathworld.wolfram.com/PartialDerangement.html
注1:如果假定完全排序的排列不计算,公式是正确的。
注2:我稍微改变了一下这个问题以使其更加清晰,因此也改为代码 - 这应该通过ShreevatsaR的评论来重新构建。
答案 0 :(得分:2)
包含 m 固定点的 n 元素的集合的排列数为
D(n,m) = \frac{n!}{m!}\sum_{k=0}^{n-m}\frac{(-1)^k}{k!} http://bit.ly/aaKqUq
因此,概率是D(n,m)/ n !,即
d(n,m) = \frac{1}{m!}\sum_{k=0}^{n-m}\frac{(-1)^k}{k!} http://bit.ly/aVqSkA
答案 1 :(得分:0)
您需要以封闭形式解决此问题的两个定义:
置换N人的方法数量为N! (N阶乘),或N * N-1 * N-2 * ...... * 1.这些被称为排列。
从N中选择M个人的方式被称为(N选择M),它等于N! /(M!(N-M)!) - 这些被称为组合。 (如果这对您来说是新手,请在Google上搜索“排列和组合”。)
我正在研究封闭式解决方案......