數字拆分問題演算法回溯 演算法講解之回溯法

2021-10-16 23:34:13 字數 2228 閱讀 3790

回溯演算法

如迷宮問題:進入迷宮後,先隨意選擇乙個前進方向,一步步向前試探前進,如果碰到死胡同,說明前進方向已無路可走,這時,首先看其它方向是否還有路可走,如果有路可走,則沿該方向再向前試探;如果已無路可走,則返回一步,再看其它方向是否還有路可走;如果有路可走,則沿該方向再向前試探。按此原則不斷搜尋回溯再搜尋,直到找到新的出路或從原路返回入口處無解為止。

演算法框架

遞迴回溯法演算法框架[一]

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 選擇列表 排除不合法選擇 做...