排列组合问题相关知识

排列组合问题

这篇随笔讲解信息学奥林匹克竞赛比较常见的一种题型——排列组合问题。阅读并理解本篇随笔要求读者具有不低于高中一年级的数学素养,并且了解信息学中递归、深搜算法的基本实现方式,能理解一般的递归程序。

上课!!

1、排列和组合的定义

(1)排列的定义

(n)个不同元素中,选出(m)个元素按照一定顺序排成一列,叫做从(n)个不同元素中取出(m)个元素的一个排列。

(2)排列数的定义

(n)个元素中选出(m)个元素的所有排列的个数,叫做从(n)个不同元素中取出(m)个元素的排列数。

(3)全排列的定义

(n=m)时所有的排列情况叫做全排列

(4)组合的定义

(n)个不同元素中,选出(m)个元素并成一组,叫做从(n)个不同元素中取出(m)个元素的一个组合。

(5)组合数的定义

(n)个元素中选出(m)个元素的所有组合的个数,叫做从(n)个不同元素中取出(m)个元素的组合数。

(6)排列&组合的区别

通俗地说,组合不分顺序,而排列分顺序,也就是说,对于数列(1,2),有以下两种排列:(1,2)(2,1),但是仅有一种组合(1,2)(2,1).

2、排列&组合的公式

(1)关于排列的公式

(n)个不同元素中,选出(m)个元素的排列数,数学表示为:(A_n^m).

计算公式如下:

[A_n^m=n(n-1)(n-2)cdots(n-m+1)=frac{n!}{(n-m)!} ]

(2)关于组合的公式

(n)个不同元素中,选出(m)个元素的组合数,数学表示为:(C_n^m).

计算公式如下:

[C_n^m=frac{A_n^m}{m!}=frac{n!}{m!(n-m)!} ]

(3)关于全排列的公式

某个数列的全排列数(f(n)),计算公式如下:

[f(n)=n! ]

3、全排列的求法

例题:生成全排列(深搜基础题)

题目链接

给定(n),生成(1-n)的全排列。

我们考虑用递归来解决全排列问题:

递归出口是当x==n+1地时候,绝对不能仅仅等于n!!

我们的递归部分使用标记数组和数列数组实现,具体实现方法可以参照下图:

我们递归的过程大体是以下的思路:

三个数位可能出现1-3每个数,所以我们使用递归算法求解的时候,先圈定这一个值,然后继续下搜,遍历完这“一条链”的时候,就上回一个数位看看还有没有其他选择,这样就保证了解不重不漏。

例题代码:

#include<bits/stdc++.h>
using namespace std;
int n,a[20],v[20];
void dfs(int x)
{
    if(x==n+1)
    {
        for(int i=1;i<n;i++)
            printf("%d ",a[i]);
        printf("%d
",a[n]);
        return;
    }
    for(int i=1;i<=n;i++)
    {
        if(v[i]==0)
        {
            a[x]=i;
            v[i]=1;
            dfs(x+1);
            v[i]=0;
        }
    }
}
int main()
{
    scanf("%d",&n);
    dfs(1);
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/11358009.html