1. 程式人生 > >有關多重集合的排列和組合問題

有關多重集合的排列和組合問題

轉載自大佬


一、先來回顧一下無重複元素的排列組合定義

排列,英文名為Permutation,是指從某元素集合中取出指定個數的元素進行排序

組合,英文名為Combination,是指從某元素集合中僅僅取出指定個數的元素,不考慮排序

從有n個不同元素的集合任取r個元素的排列方式有:P(n, r) = n*(n-1)*...*(n-r+1) = n! / (n-r)!,特別地 P(n,n) = n!

從有n個不同元素的集合任取r個元素的組合方式有:C(n, r) = P(n, r) / r! = n! / ( (n-r)! * r!),特別地C(n,n) = 1

二、下面我們來定義多重集合(multiset)的排列組合

設多重集合 S = { n1 * a1, n2 * a2, ..., nk * ak },n = n1 + n2 + ... + nk

即集合 S 中含有n1個元素a1, n2個元素a2,...,nk個元素ak,ni被稱為元素ai的重數,k成為多重集合的類別數

在 S 中任選 r 個元素的排列稱為S的r排列,當r = n時,有公式 P(n; n1*a1, n2*a2, ..., nk*ak) = n! / (n1! * n2! * ...* nk!)//(一共n個位置,第一個位置為n種,第2個n-1種...總共n!種,然後對於ni去重)

在 S 中任選 r 個元素的組合稱為S的r組合

,當r<=任意ni時,有公式 C(n; n1*a1, n2*a2, ..., nk*ak) = C(k+r-1, r)

,//C(k+r-1,k-1)

由公式可以看出多重集合的組合只與類別數k 和選取的元素r 有關,與總數無關!

如何將問題描述轉化成多重集合問題的排列組合呢?

三、下面我們來看一些有關多重集合問題的例子

例1:線性方程 x1 + x2 + ... + xk = r 一共有多少組非負整數解?

解答:上述不定方程的非負整數解對應於下述排列

1...101...1 01...1 0 ...... 01...1

x1 個    x2 個   x3 個   ......  xk 個

其中 k-1個 0 將 r 個 1 分成k段, 每段含1的個數分別為 x1, x2, ..., xk, 

很明顯這個排列是多重集合 S = { r * 1, (k-1)* 0 }的全排列

即:P(r+k-1; r*1, (k-1)*0) = (r+k-1)! / ( r! * (k-1)! ) = C( r+k-1, r),即從k類元素中選r個的種類

//C(r+k-1,k-1) 轉化成r個小球放在k個小盒子裡,允許有空盒的問題.

例二:某車站有6個入口處,每個入口處每次只能進一個人, 一組9個人進站的方案有多少?

解答:進站方案可以表示為 

1 011 011 01 011 01 

g1  g2   g3   g4  g5   g6

其中 1 表示不同的人, 而 0 表示門框, 6-1= 5個門框將序列分為六段,

則任意進站方案可表示成上面 14 個元素 S = { 5 * 1, 1 * p1, 1 * p2, ..., 1 * p9 }的一個排列

即:P(5+9;5*1, 1*p1, 1*p2, ..., 1*p9) = 14! / ( 5! * 1! * .... 1! ) = 14! / 5!

//可以這樣來想,9個人進站,有的入口可能一個人都不經過,所以我們用擋板法將將其分給六個入口,因為可能有空的,再次轉化成9個小球,

放入6歌小盒有空盒問題,因為是個排列,在乘以A(9,9)

例三、求從(0,0)點到(m,n)點的非降路徑數

解答:無論哪條路徑,必須在x方向上走m步,y方向上走n步,將非降路徑數與多重集合 S = { m * x, n * y } 的排列建立一一對應關係,所以格路總數為 P(m+n; m*x, n*y) = (m+n)! / ( m! * n! ) = C(m+n, n) = C(m+n, m)

一般地,設c>=a, d>=b,則由(a,b)到(c,d)的非降路徑數為C(c-a+d-b, c-a)

擴充套件問題: 在上例基礎上若設m<n,求點(0,1)到點(m,n)不接觸對角線 y=x的非降路徑資料(接觸包括穿過)

解答:從(0,1)到(m,n)的非降路徑,有的接觸 y=x,有的不接觸,對於每條接觸 y=x的非降路徑,做(0,1)關於y=x的對稱點(1,0)到(m,n)的對稱非降路徑,容易看出從(0,1)到(m,n)接觸y=x的非降路徑與 (1,0)到(m,n)的非降路徑(必穿過y=x)一一對應,

故所求的非降路徑數為C(m+n-1, m) - C(m+n-1, m-1)

例四、將r個相同的小球放入n個不同的盒子,總共有多少種方案?

解答:該問題可以轉化為r個相同的小球與n-1個相同的盒壁的排列問題

1...1 0 1...1 0 1...1 0 ...... 0 1...1

其中有 n-1個 0 分成 n段,每段表示不同的盒子, 每段中1的個數表示該盒子裡放入的小球總數,總共r個1

即:P( r+n-1; r*1, (n-1)*0 ) = (r+n-1)! / ( r! * (n-1)! ) = C( r+n-1, r)

例五、求集合 X = { 1,2,..., n }的不含相鄰整數的k元子集個數

解答:任意一個X的k元子集s都可以對應於一個由0,1組成的有序n重組(a1 a2 ... an),其中 ai = 1 當 i屬於s,否則 ai = 0,當i不屬於s,由於s中不含相鄰整數,所以在此n重組中沒有兩個1是相鄰的,所以子集s是與這樣的n重組 S = { k*1, (n-k)*0 }之間是一一對應的,由於任意兩個1彼此不相鄰,故可以把(n-k)個0依次排列,然後在(n-k+1)個空隙中插入k個1,所以從(n-k+1)個空隙中選擇k個位置來放置1,有 C(n-k+1, k) 種選法,這也是原問題所對應的答案。//插空法


相關推薦

有關多重集合排列組合問題

轉載自大佬 一、先來回顧一下無重複元素的排列組合定義 排列,英文名為Permutation,是指從某元素集合中取出指定個數的元素進行排序 組合,英文名為Combination,是指從某元素集合中僅僅取出指定個數的元素,不考慮排序 從有n個不同元素的集合

多重集合排列組合問題

一、先來回顧一下無重複元素的排列組合定義 排列,英文名為Permutation,是指從某元素集合中取出指定個數的元素進行排序 組合,英文名為Combination,是指從某元素集合中僅僅取出指定個數的元素,不考慮排序 從有n個不同元素的集合任取r個元素的排列方式有:P(

排列組合的求解

不能 結果 整體 條件 構造 討論 個數 女生 排除法 1)使用“分類計數原理”還是“分步計數原理”要根據我們完成某件事時采取的方式而定,可以分類來完成這件事時用“分類計數原理”,需要分步來完成這件事時

字符串的排列組合問題

函數表 out 跳過 lis ++ else += 過程 pow 1、字符串的全排列 題目:{a,b,c}要求輸出{abc,acb,bac,bca,cab,cba}。 字符串全排列可以把字符串看成兩個部分,第一個部分為它的一個字符,第二部分是後面的字符。 分兩步完成:首先求

C++ STL求全排列組合

C++11 STL內建了求全排列的模板函式next_permutation和prev_permutation,屬於<algorithm>標頭檔案和std名稱空間,使用非常方便。例如: vector<int> A{1,2,3,4,5};

排列組合函式

定義: 排列組合是組合學最基本的概念。所謂排列,就是指從給定個數的元素中取出指定個數的元素進行排序。組合則是指從給定個數的元素中僅僅取出指定個數的元素,不考慮排序。 排列的定義:從n個不同元素中,任取m(m≤n,m與n均為自然數,下同)個元素按照一定的順序排成一列,叫做從n個不同元素中取出m個元素

[收集]字串的全排列組合

今天學習了一下何海濤部落格中的第28題,字串的排列問題,實際上指的是字串的全排列問題(排列和全排列還是有區別的吧)。思考並研究了這題之後就考慮了一下不同條件下其他類似的題的解法的編寫,兩部分來自於何海濤,其他來自於網路,此處做搬運和收集工作。分別從四個方面考慮:一、字串的全

給定一個數組,求出陣列元素的排列組合——Java實現

1. 思路 組合數C(n,m)和全排列A(n,n)可以通過遞迴的方式,直接實現。 而A(n,m)則可以通過組合數和全排列間接求出A(n,m)=C(n,m)*A(m,m),即對得到的組合數中的每個元素進行全排列 2. Java實現 package com.zfy.test

基於C#的排列組合演算法

using System;using System.Collections.Generic; namespace Algorithms{    public class PermutationAndCombination<T>    {        /// &l

排列組合演算法的C#語言實現

using System; namespace Util.Comp { public class CombinationPermutation { public static void Main() { //全排列使用方法

利用字典序生成下一個排列組合的方法

先介紹生成排列的方法最簡單的方法是用STL自帶的next_permutation() 引數為要生成下一個排列的區間int n, p[10]; cin >> n; for (int i = 0; i < n; i++) cin >> p[i];

字串排列組合的JAVA實現

字串的組合: 給一個字串,比如ABC, 把所有的組合,即:A, B, C, AB, AC, BC, ABC, 都找出來。 解題思路: 假設我們想在長度為n的字串中求m個字元的組合。我們先從頭掃描字串的第一個字元。針對第一個字元,我們有兩種選擇:一是把這個字元放到組合

字串的全排列組合演算法(遞迴非遞迴)

全排列在筆試面試中很熱門,因為它難度適中,既可以考察遞迴實現,又能進一步考察非遞迴的實現,便於區分出考生的水平。所以在百度和迅雷的校園招聘以及程式設計師和軟體設計師的考試中都考到了,因此本文對全排列作下總結幫助大家更好的學習和理解。對本文有任何補充之處,歡迎大家指出。

排列組合實現

.html 有意義 per more tro 包含 方法 循環 -s 記得@老趙之前在微博上吐槽說,“有的人真是毫無長進,六年前某同事不會寫程序輸出全排列,昨天發郵件還是問我該怎麽寫,這時間浪費到我都看不下去了。” 那時候就很好奇全排列到底是什

PHP+MySQL開發小專案的集合筆記(四)控制div的排列p標籤,從另外表讀取加工資料並規定小數點位數

需求:HTML頁面增加註釋,div盒子控制曲線大小,多個盒子相互巢狀。具體資料從另外表內獲取。 HTML頁面更改: <!-- Morris chart - Sales --> <!-- Change! -->

字串的全排列所有組合問題及打靶問題

轉自:https://blog.csdn.net/a1937935900/article/details/77103955 問題1 :輸入一個字串,打印出該字串中字元的所有排列。例如輸入字串abc,則輸出由字元a、b、c所能排列出來的所有字串abc、acb、bac、bca、cab和cba。

字串的全排列組合

全排列: 主要思想:將字串第一個字元依次與後面字元交換,然後進行遞迴交換 在存在重複字元時需要加一個判斷,判斷之前是否交換過此字元。 bool isSwap(string str, int begin, int end) { for (int i = be

深度優先演算法求含有N個元素的集合的全部組合(即:在集合中選1,2,3...N個元素的所有組合,不是排列)

先來看一道題:給定整數:a1, a2, a3.....an, 判斷是否可以從中選出任意個數,使其和等於K, (數字的個數,取1--N個數都可以), 這道題要求找出這N個數中選1,2,3...N個元素的所有組合,如果任何一個組合滿足和為K, 就找到了答案,所以:本質上,這道題

python類繼承組合

date 子類 read ini import class mon python write 在python3中所有類默認繼承object,凡是繼承了object的類都成為新式類,以及該子類的子類Python3中所有的類都是新式類,沒有集成object類的子類成為經典類(在