子集和問題 SDUT OJ 搜尋演算法 回溯

2021-10-10 23:32:39 字數 1641 閱讀 7518

子集和問題的乙個例項為〈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 

5 10

2 2 6 5 4

output 

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估價函式越接近真實值演算法越優,但一定不能大於真實值,否則...