子集和問題的乙個例項為〈s,t〉。其中,s=是乙個正整數的集合,c是乙個正整數。子集和問題判定是否存在s的乙個子集s1,使得:
試設計乙個解子集和問題的回溯法。
對於給定的正整數的集合s=和正整數c,計算s 的乙個子集s1,使得:
輸入資料的第1 行有2 個正整數n 和c(n≤10000,c≤10000000),n 表示s 的大小,c是子集和的目標值。接下來的1 行中,有n個正整數,表示集合s中的元素。
將子集和問題的解輸出。當問題無解時,輸出「no solution!」。
input
output5 10
2 2 6 5 4
/***2 2 6
題意:從集合s中找到一組數,令這組數的和等於c
對n個數,從s[0]到s[n-1]逐個遍歷,每個數都有 「要」 和 「不要」 兩個選擇,
這樣遍歷會生成乙個二叉樹,
遍歷過程中,若已選擇的數總和大於所需的值,則返回上層,
若不大於,則繼續向深處遍歷,判斷還需要選擇哪個數
剪枝:dfs搜尋會形成二叉樹,剪枝就是把不需要再忘深處遞迴的樹枝剪掉,減少遞迴
參考:回溯演算法套路詳解 - labuladong的文章 - 知乎
***/
#include #include /// scanf() printf()
using namespace std;
/***
題意:從集合s中找到一組數,令這組數的和等於c
解題思路:
對n個數,從s[0]到s[n-1]逐個遍歷,每個數都有 「要」 和 「不要」 兩個選擇,
這樣遍歷會生成乙個二叉樹,
遍歷過程中,若已選擇的數總和大於所需的值,則返回上層,
若不大於,則繼續向深處遍歷,判斷還需要選擇哪個數
剪枝:dfs搜尋會形成二叉樹,剪枝就是把不需要再忘深處遞迴的樹枝剪掉,減少遞迴
參考:***/
int n;
int c;
int s[10005];///儲存集合s中的數
int ans[10005];///儲存找出的一組數
int num = 0;///記錄結果陣列ans中有幾個數
int flag = 0;///標記 能否從集合s中找到符合題意的一組數
///深度搜尋函式,搜尋符合條件的數,
void dfs(int pos, int sum);///引數為陣列s的下標pos和當前位置已經找出的一組數的總和值
int main()
flag = 0;///標記 能否從集合s中找到符合題意的一組數
if(sum == c)
else if(sum < c)
else
if(flag)
}else
return 0;
}void dfs(int pos, int sum)
else if(sum > c)
if(pos == n)
for(int i = pos; i < n; i++)
else}}
搜尋演算法(迷宮問題)
盼來盼去終於又要開始學習演算法了!筆者自學演算法,所以學習順序以個人舒服的形式!用例子來看 問題 有乙個迷宮,以1 2形式來表示 1表示是空地,即可以行走,2表示是障礙物,即無法通行。該迷宮由乙個矩陣形式表示。即1 1 2 1 1 1 1 1 1 1 2 1 1 2 1 1 1 1 1 2 有終點和...
A 搜尋演算法
啟發式搜尋演算法 要理解 a 搜尋演算法,還得從啟發式搜尋演算法開始談起。所謂啟發式搜尋,就在於當前搜尋結點往下選擇下一步結點時,可以通過乙個啟發函式 來進行選擇,選擇代價最少的結點作為下一步搜尋結點而跳轉其上 遇到有乙個以上代價最 少的結點,不妨選距離當前搜尋點最近一次展開的搜尋點進行下一步搜尋 ...
A 搜尋演算法
a 演算法是基於bfs的一種入門級啟發式搜尋演算法,就是將bfs的佇列改為基於估價的優先佇列,可以快速地找到答案。優先隊列為小根堆 while 優先佇列不為空 取出隊頭並擴充套件 將擴充套件節點以估價值 當前值為優先順序入隊 endwhile估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...