排列與組合

2021-08-30 03:24:34 字數 1593 閱讀 1246

試想這樣乙個問題

一組數比如 任取其中的三邊,會構成多少種不同的三角型

又或者任取其中四邊,會構成多少種不同的多邊形?如果取三邊,或五邊又如何?

在一些情況下,我們需要解決處理排列和組合數的問題

先來看一下排列的情況

abcd

下標 1234

解決乙個陣列平移的問題並不難

abcd 向左移動4次,就可以滿足在1的位置上都出現一次。

那麼緊接著下一步,如何讓2的位置再次輪流出現abcd也仍然是使用相同的方法

每次移動一位後,檢視右邊的n個數,然後把問題拋給子問題

遞迴,分治法,是計算機解決問題的乙個主要的手段

我們從問題中發現相似的處理方法,然後遞迴呼叫自身

[code]

int a = ;

// level start at 0

public void rotate(int level)

}[/code]

實際上我們做的就是旋轉整個陣列,當開始旋轉n個數中的第乙個數時,首先詢問右邊n-1個數是否已經旋轉完成?如果沒有則進入旋轉右邊的n-1個數的方法中,同理進入這個方法後再次詢問右邊n-2個數是否旋轉完成?一直到最後1個數或是最後2個數已經旋轉完成時,跳回到上級方法中繼續執行。

組合:解決了排列的問題後,再來看組合就容易了許多,我們取c(4,2)的組合。紅色代表取到的數

[color=red]ab[/color]cd

[color=red]a[/color]b[color=red]c[/color]d

[color=red]a[/color]bc[color=red]d[/color]

a[color=red]bc[/color]d

a[color=red]b[/color]c[color=red]d[/color]

ab[color=red]cd[/color]

同排列,我們也在不斷的遍歷整個陣列,每次詢問是否子問題已經解決,即n+1位後的數是否已經全部遍歷了?然後決定是否進入子問題。這裡由於組合數取的範圍,我們需要不斷向右移動。在中,移動了紅色編號的起始位置

解決了組合問題後,之前的多邊型的題目就很簡單了,在這裡我們沒有列舉諸如2邊相同的情況如取其中3變可以構成多少個三角型,實際只有2,2,2 一種。因為所有的邊都是相同的,因此還需要一些判斷。另外乙個多邊型的任何一邊必須小於其它所有邊相加。

組合與排列**:

[code]

public class polygons;

int b = new int[4];

//x為起始位置,設為0表從陣列的第乙個位置開始迴圈

public void rotate1(int x) }/*

* x為0,意為從陣列0的位置開始

* level為-1,描述迴圈層數

* y為取陣列中的幾個數作為組合,如取1則表示陣列中的任意2個數的組合

*/public void rotate2(int x, int y, int level)

}public void log(int b)

system.out.println("");

}public static void main(string args)

}[/code]

排列與組合

include using namespace std void perm int a,int n,int m,int out,int k,int used cout endl for int i 0 i n i void combine int a,int n,int m,int out,int ...

組合與排列

定義 從 n 個不同元素的集合中,任意取出 m m n 個元素排成一列 有先後順序 稱為乙個排列 此種排列的總數即為排列數,即叫做從 n 個不同元素中取出 m 和元素的排列數。公式 當 n m 時,分母為 0 1,即為全排列 推導 在具有 n 個數的集合中,順序取出 m 個數,成為乙個排列。上述過程...

排列與組合 回溯

求1.n的全排序或者m組合實際上是乙個回溯問題,對於回溯問題,如何寫出遞迴程式,關鍵在於想好問題隱式解空間樹,之後,可以按照標準的dfs去遍歷解空間樹,並在適當的時候剪枝,對於全排列,不需要也不能進行減枝,每個葉子節點都對應乙個全排列。對於組合問題,實際上只要限定,產生m個數的下標是從小到大排列的就...