排列組合問題相關知識


排列組合問題

這篇隨筆講解信息學奧林匹克競賽比較常見的一種題型——排列組合問題。閱讀並理解本篇隨筆要求讀者具有不低於高中一年級的數學素養,並且了解信息學中遞歸、深搜算法的基本實現方式,能理解一般的遞歸程序。

上課!!

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\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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM