排列组合问题相关知识

排列组合问题

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

上课!!

一、排列和组合的定义

(1)排列的定义

\(n\)个不一样元素中,选出\(m\)个元素按照必定顺序排成一列,叫作从\(n\)个不一样元素中取出\(m\)个元素的一个排列。c++

(2)排列数的定义

\(n\)个元素中选出\(m\)个元素的全部排列的个数,叫作从\(n\)个不一样元素中取出\(m\)个元素的排列数。算法

(3)全排列的定义

\(n=m\)时全部的排列状况叫作全排列数组

(4)组合的定义

\(n\)个不一样元素中,选出\(m\)个元素并成一组,叫作从\(n\)个不一样元素中取出\(m\)个元素的一个组合。spa

(5)组合数的定义

\(n\)个元素中选出\(m\)个元素的全部组合的个数,叫作从\(n\)个不一样元素中取出\(m\)个元素的组合数。3d

(6)排列&组合的区别

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

二、排列&组合的公式

(1)关于排列的公式

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

计算公式以下:
\[ A_n^m=n(n-1)(n-2)\cdots(n-m+1)=\frac{n!}{(n-m)!} \]递归

(2)关于组合的公式

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

计算公式以下:
\[ C_n^m=\frac{A_n^m}{m!}=\frac{n!}{m!(n-m)!} \]

(3)关于全排列的公式

某个数列的全排列数\(f(n)\),计算公式以下:
\[ f(n)=n! \]

三、全排列的求法

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

题目连接

给定\(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\n",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;
}
相关文章
相关标签/搜索