幾種常見的演算法

2021-07-02 07:33:27 字數 2154 閱讀 1253

1、窮舉法

窮舉法是最基本的演算法設計策略,其思想是列舉出問題所有的可能解,逐一進行判別,找出滿足條件的解.

窮舉法的運用關鍵在於解決兩個問題:

在運用窮舉法時,容易出現的問題是可能解過多,導致演算法效率很低,這就需要對列舉可能解的方法進行優化.

以題1041--純素數問題為例,從1000到9999都可以看作是可能解,可以通過對所有這些可能解逐一進行判別,找出其中的純素數,但只要稍作分析,就會發現其實可以大幅度地降低可能解的範圍.根據題意易知,個位只可能是3、5、7,再根據題意可知,可以在3、5、7的基礎上,先找出所有的二位純素數,再在二位純素數基礎上找出三位純素數,最後在三位純素數的基礎上找出所有的四位純素數.

2、分治法

分治法也是應用非常廣泛的一種演算法設計策略,其思想是將問題分解為若干子問題,從而可以遞迴地求解各子問題,再綜合出問題的解.

分治法的運用關鍵在於解決三個問題:

我們熟知的如漢諾塔問題、折半查詢演算法、快速排序演算法等都是分治法運用的典型案例.

以題1045--square coins為例,先對題意進行分析,可設乙個函式f(m,n)等於用面值不超過n2的貨幣構成總值為m的方案數,則容易推導出:

f(m,n) = f(m-0*n*n,n-1)+f(m-1*n*n,n-1)+f(m-2*n*n,n-1)+...+f(m-k*n*n,n-1)

這裡的k是幣值為n2的貨幣最多可以用多少枚,即k=m/(n*n).

也很容易分析出,f(m,1) = f(1,n) = 1

對於這樣的題目,一旦分析出了遞推公式,程式就非常好寫了.所以在動手開始寫程式之前,分析工作做得越徹底,邏輯描述越準確、簡潔,寫起程式來就會越容易.

3、動態規劃法

動態規劃法多用來計算最優問題,動態規劃法與分治法的基本思想是一致的,但處理的手法不同.動態規劃法在運用時,要先對問題的分治規律進行分析,找出終結子問題,以及子問題向父問題歸納的規則,而演算法則直接從終結子問題開始求解,逐層向上歸納,直到歸納出原問題的解.

動態規劃法多用於在分治過程中,子問題可能重複出現的情況,在這種情況下,如果按照常規的分治法,自上向下分治求解,則重複出現的子問題就會被重複地求解,從而增大了冗餘計算量,降低了求解效率.而採用動態規劃法,自底向上求解,每個子問題只計算一次,就可以避免這種重複的求解了.

動態規劃法還有另外一種實現形式,即備忘錄法.備忘錄的基本思想是設立乙個稱為備忘錄的容器,記錄已經求得解的子問題及其解.仍然採用與分治法相同的自上向下分治求解的策略,只是對每乙個分解出的子問題,先在備忘錄中查詢該子問題,如果備忘錄中已經存在該子問題,則不須再求解,可以從備忘錄中直接得到解,否則,對子問題遞迴求解,且每求得乙個子問題的解,都將子問題及解存入備忘錄中.

例如,在題1045--square coins中,可以採用分治法求解,也可以採用動態規劃法求解,即從f(m,1)和f(1,n)出發,逐層向上計算,直到求得f(m,n).

在競賽中,動態規劃和備忘錄的思想還可以有另一種用法.有些題目中的可能問題數是有限的,而在一次執行中可能需要計算多個測試用例,可以採用備忘錄的方法,預先將所有的問題的解記錄下來,然後輸入乙個測試用例,就查備忘錄,直接找到答案輸出.這在各問題之間存在父子關係的情況下,會更有效.例如,在題1045--square coins中,題目中已經指出了最大的目標幣值不超過300,也就是說問題數只有300個,而且各問題的計算中存在重疊的子問題,可以採用動態規劃法,將所有問題的解先全部計算出來,再依次輸入測試用例資料,並直接輸出答案.

4、回溯法

回溯法是基於問題狀態樹搜尋的求解法,其可適用範圍很廣.從某種角度上說,可以把回溯法看作是優化了的窮舉法.回溯法的基本思想是逐步構造問題的可能解,一邊構造,一邊用約束條件進行判別,一旦發現已經不可能構造出滿足條件的解了,則退回上一步構造過程,重新進行構造.這個退回的過程,就稱之為回溯.

回溯法在運用時,要解決的關鍵問題在於:

回溯法的經典案例也很多,例如全排列問題、n後問題等.

5、貪心法

貪心法也是求解最優問題的常用演算法策略,利用貪心法策略所設計的演算法,通常效率較高,演算法簡單.貪心法的基本思想是對問題做出目前看來最好的選擇,即貪心選擇,並使問題轉化為規模更小的子問題.如此迭代,直到子問題可以直接求解.

基於貪心法的經典演算法例如:哈夫曼演算法、最小生成樹演算法、最短路徑演算法等

幾種常見的排序演算法

氣泡排序演算法的運作如下 1 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。2 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。3 針對所有的元素重複以上的步驟,除了最後乙個。4 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要...

幾種常見的排序演算法

1.氣泡排序 void bubble sort int array,int n if 1 flag break printf d i return 2.快速排序 好 void quicksort int a,int left,int right left是選擇的軸點,如0,表示這個資料為軸點,rig...

幾種常見的排序演算法

氣泡排序 void sort1 int nsort,int nlength if benter false 插入排序 void sort2 int nsort,int nlength else nsort nsign ntemp 選擇排序 void sort3 int nsort,int nleng...