回溯演算法
如迷宮問題:進入迷宮後,先隨意選擇乙個前進方向,一步步向前試探前進,如果碰到死胡同,說明前進方向已無路可走,這時,首先看其它方向是否還有路可走,如果有路可走,則沿該方向再向前試探;如果已無路可走,則返回一步,再看其它方向是否還有路可走;如果有路可走,則沿該方向再向前試探。按此原則不斷搜尋回溯再搜尋,直到找到新的出路或從原路返回入口處無解為止。
演算法框架
遞迴回溯法演算法框架[一]
int search(int k)
for (i=1;i<=算符種數;i++)
if (滿足條件)
儲存結果
if (到目的地) 輸出解;
else search(k+1);
恢復:儲存結果之前的狀態
遞迴回溯法演算法框架[二]
int search(int k)
if (到目的地) 輸出解;
else
for (i=1;i<=算符種數;i++)
if (滿足條件)
儲存結果;
search(k+1);
恢復:儲存結果之前的狀態
例題講解
【例1】素數環:從1到20這20個數擺成乙個環,要求相鄰的兩個數的和是乙個素數。
【演算法分析】
非常明顯,這是一道回溯的題目。從1開始,每個空位有20種可能,只要填進去的數合法:與前面的數不相同;與左邊相鄰的數的和是乙個素數。第20個數還要判斷和第1個數的和是否素數。
【演算法流程】
1、資料初始化; 2、遞迴填數:判斷第i個數填入是否合法;
#include
#include
#include
#include
using namespace std;
bool b[21]=;
int total=0,a[21]=;
int search(int); //回溯過程
int print(); //輸出方案
bool pd(int,int); //判斷素數int main()
search(1);
cout<
int search(int t)
int i;
for (i=1;i<=20;i++) //有20個數可選 if (pd(a[t-1],i)&&(!b[i])) //判斷與前乙個數是否構成素數及該數是否可用
else search(t+1);
b[i]=0;
int print()
total++;
cout<";
for (int j=1;j<=20;j++)
cout<
cout<
bool pd(int x,int y)
int k=2,i=x+y;
while (k<=sqrt(i)&&i%k!=0) k++;
if (k>sqrt(i)) return 1;
else return 0;
【例2】設有n個整數的集合{1,2,…,n},從中取出任意r個數進行排列(r
#include
#include
#include
using namespace std;
int num=0,a[10001]=,n,r;
bool b[10001]=;
int search(int); //回溯過程
int print(); //輸出方案
int main()
cout<
cin>>n>>r;
search(1);
cout<
int search(int k)
int i;
for (i=1;i<=n;i++)
if (!b[i]) //判斷i是否可用 ,n,total;
int search(int,int);
int print(int);
int main()
cin>>n;
search(n,1);
//將要拆分的數n傳遞給s cout<
int search(int s,int t)
int i;
for (i=a[t-1];i<=s;i++)
if (i
//當前數i要大於等於前1位數,且不過n
int print(int t)
cout<
for (int i=1;i<=t-1;i++)
//輸出一種拆分方案 cout<
回溯演算法 整數拆分問題
洛谷p2404.簡單的回溯法實現,輸入乙個數字n,求出1到n 1中相加和是n的算式。用乙個ans陣列儲存探索到的每乙個數字,在dfs函式中用減法的形式得到和什麼時候到達了n,到達n也就是temp變為0的時候。同時又根據例項,沒有重複的算式,乙個數字可以用多次,所以i的起始位置要設定乙個start來表...
詳細講解回溯演算法(一)
本篇博文先不根據樣例講解演算法,我會在接下的博文中一一講解回溯法的具體運用。這裡先詳細講解回溯演算法的原理和思路。在了解回溯演算法之前,先對回溯演算法中涉及的知識點的概念先講解下,方便理解博文,哈哈大家不要嫌囉嗦,可能都想直接了解什麼是回溯法,但基礎不好,後面的運用又怎能徹底掌握呢,不要嫌麻煩,多點...
回溯演算法問題
回溯問題,其實就是乙個決策樹遍歷。要考慮三個問題。其實回溯問題可以理解為動規的暴力解法,而且是沒有重疊子問題的動規。result public void backtrack 路徑,選擇列表 if 滿足結束條件 result.add 路徑 return for 選擇 in 選擇列表 排除不合法選擇 做...