試想這樣乙個問題
一組數比如 任取其中的三邊,會構成多少種不同的三角型
又或者任取其中四邊,會構成多少種不同的多邊形?如果取三邊,或五邊又如何?
在一些情況下,我們需要解決處理排列和組合數的問題
先來看一下排列的情況
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個數的下標是從小到大排列的就...