根据条件枚举一组排列

时间:2010-08-15 05:37:03

标签: c++ math permutation

我已经能够使用std :: next_permutation(c ++)等解决以下问题, 但我现在正在考虑更普遍,并且非常想形成一个 因为这种类型的问题似乎有助于表达 - 尽管我现在还没有运气。

以下是问题:

鉴于与N名选手的比赛正在进行,准确的M选手将在与他们的球衣上的数字相同的位置完成的概率是多少。 其中M <= N。

到目前为止我做了什么:

  1. 会有N!种族可以结束的方式,

  2. 我试过摆弄一个由三个或四个参赛者组成的问题的小变种 满足条件的所需人数为2.在两种情况下按特定顺序完成的2人概率为1/2

  3. 我想知道是否已经存在某种处理所有情况的表达式?

    一些代码:

    #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的评论来重新构建。

2 个答案:

答案 0 :(得分:2)

答案 1 :(得分:0)

您需要以封闭形式解决此问题的两个定义:

  1. 置换N人的方法数量为N! (N阶乘),或N * N-1 * N-2 * ...... * 1.这些被称为排列

  2. 从N中选择M个人的方式被称为(N选择M),它等于N! /(M!(N-M)!) - 这些被称为组合。 (如果这对您来说是新手,请在Google上搜索“排列和组合”。)

  3. 我正在研究封闭式解决方案......