排列組合問題相關知識

排列組合問題

這篇隨筆講解信息學奧林匹克競賽比較常見的一種題型——排列組合問題。閱讀並理解本篇隨筆要求讀者具備不低於高中一年級的數學素養,而且瞭解信息學中遞歸、深搜算法的基本實現方式,能理解通常的遞歸程序。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;
}
相關文章
相關標籤/搜索