c – 根据条件枚举一组排列

我已经能够使用std :: next_permutation(c)等解决以下问题,

但我现在正在考虑更普遍,并且非常想形成一个

因为这种类型的问题似乎有助于表达自己 – 尽管我还没有任何运气.

这是一个问题:

鉴于与N名参赛者的比赛正在进行,准确的M参赛者完成的位置与衬衫上的数字相同的概率是多少.
其中M <= N. 到目前为止我做了什么:
>会有N!比赛结束的方式,
>我试过摆弄一个由3或4名参赛者组成的问题的小变种
满足条件的所需人数为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的评论重新编写.

最佳答案 包含m个固定点的n个元素的集合的排列数是

D(n,m) = \frac{n!}{m!}\sum_{k=0}^{n-m}\frac{(-1)^k}{k!} http://bit.ly/aaKqUq

(见http://en.wikipedia.org/wiki/Random_permutation_statistics#Number_of_permutations_that_are_derangements)

因此,概率是D(n,m)/ n!,即

d(n,m) = \frac{1}{m!}\sum_{k=0}^{n-m}\frac{(-1)^k}{k!} http://bit.ly/aVqSkA

点赞