以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皇后問題效果挺好的 請參考 而且思路也很清楚 為什麼還要去多加乙個棧呢 原因在於 為了更好的訓練演算法及資料結構的應用 達到融會貫通的目的 做些遞迴與非遞迴程式間的轉換是起碼的...
演算法基礎 遞迴與回溯 遞推 迭代關係
優點 更簡潔清晰,可讀性更好 實際上遞迴的 更清晰,但是從學習的角度要理解遞迴真正發生的什麼,是如何呼叫的,呼叫層次和路線,呼叫堆疊中儲存了什麼,可能是不容易。但是不可否認遞迴的 更簡潔。缺點 由於遞迴需要系統堆疊,所以空間消耗要比非遞迴 要大很多.而且,如果遞迴深度太大,可能會造成棧溢位 遞迴 詳...