回溯法的遞迴與迭代版本

2021-10-04 14:35:25 字數 1535 閱讀 7237

以2019藍橋杯c/c++b組的兩個題目為例,來進行說明回溯法的遞迴和迭代版本

作為籃球隊教練,你需要從以下名單中選出 1 號位至 5 號位各一名球員,組成球隊的首發陣容。每位球員擔任 1 號位至 5 號位時的評分如下表所示。請你計算首發陣容 1號位至 5 號位的評分之和最大可能是多少?

此處的遞迴和迭代都是用於遍歷全部解空間尋找最優解,所以思路是差不多的,每個人每個位置都嘗試一下。但是這個嘗試的順序對於**的複雜度有很大的關係。我們應該固定站位資訊,每個位置的球員做迴圈,其實五層巢狀迴圈也能解決這個問題,但是那樣**就太不優雅了。

這裡歸納一下,回溯法遞迴與迭代方式之間轉換的通用方法:

由於都是在二維向量中查詢最優組合,所以我們以乙個所有元素必須取值的軸作為外層的軸物件,在這道題目中,就是以位置作為這條軸,因為這個變數可以依次取值,到第5號位的時候,就可以計算結果了,直接利用這個條件能夠減少很多判斷條件。

位置和球員之間的關係可以用乙個一維陣列表示,a[位置] = 球員,這樣在迭代回溯的過程中可以直接通過x[位置–]返回上乙個位置,x[位置]++來訪問下乙個球員,而且回溯的過程中,位置和球員的資訊被關聯到一起,使得可以進行下一次搜尋。

要注意搜尋的條件,如這道題使用一維陣列來記錄球員是否已經被選擇了,要注意回溯時相關條件的改變,比如sum之前增加過,回溯之後要把sum-前乙個加上去的值。

具體的改寫方式,見下列**。理論上都是可以改寫的。

c++**

#include

#include

#include

using

namespace std;

int a[20]

[6]=

,,,,

,,,,

,,,,

,,,,

,,,}

;int vis[21]

;//20個隊員是否被訪問過,放21是怕遍歷的時候越界

int max_score =0;

//index表明了遞迴的深度,也表明是哪個位置,sum是當前情況的總分

void

dfs(

int index,

int sum)

for(

int i=

0; i<

20; i++

)//對於每乙個隊員,每乙個位置都嘗試一下}}

void

dfs_iterator()

;//相應站位對應隊員

int sum =0;

x[1]=

-1;while

(k >0)

//控制站位數

else

}else}}

intmain()

回溯法 回溯法介紹 回溯與遞迴的區別

回溯法 有一類問題,我們不知道它明確的計算法則。而是先進行試探,試探到最終狀況,發現不滿足問題的要求,則回溯到上乙個狀態繼續試探。這種不斷試探和回溯的思想,稱為回溯法 backtrcking 此類問題包括 求最優解 一組解 全部解。例如八皇后問題 回溯的演算法思想 一直往下走,然後再一步步往回走 面...

回溯法 八皇后 堆疊實現的非遞迴版本

回溯法 八皇后 堆疊實現的非遞迴版本 by emilmatthew 05 11 9 其實,用遞迴或 while 迴圈實現 n皇后問題效果挺好的 請參考 而且思路也很清楚 為什麼還要去多加乙個棧呢 原因在於 為了更好的訓練演算法及資料結構的應用 達到融會貫通的目的 做些遞迴與非遞迴程式間的轉換是起碼的...

演算法基礎 遞迴與回溯 遞推 迭代關係

優點 更簡潔清晰,可讀性更好 實際上遞迴的 更清晰,但是從學習的角度要理解遞迴真正發生的什麼,是如何呼叫的,呼叫層次和路線,呼叫堆疊中儲存了什麼,可能是不容易。但是不可否認遞迴的 更簡潔。缺點 由於遞迴需要系統堆疊,所以空間消耗要比非遞迴 要大很多.而且,如果遞迴深度太大,可能會造成棧溢位 遞迴 詳...