子集和問題

2021-09-29 21:27:45 字數 1578 閱讀 7346

sdut oj 子集和問題鏈結

problem description

子集和問題的乙個例項為〈s,t〉。其中,s=是乙個正整數的集合,c是乙個正整數。子集和問題判定是否存在s的乙個子集s1,使得:

。試設計乙個解子集和問題的回溯法。

對於給定的正整數的集合s=和正整數c,計算s 的乙個子集s1,使得:

。input

輸入資料的第1 行有2 個正整數n 和c(n≤10000,c≤10000000),n 表示s 的大小,c是子集和的目標值。接下來的1 行中,有n個正

此問題是乙個典型的搜尋問題。需要依次嘗試每一種可能。

問題的難點在於怎樣嘗試每一種可能。

回看問題,該問題有2

^n中子集,用正常的for迴圈不可能找到問題的解,

所以只可能用遞迴實現,聯絡搜尋演算法,所以我們就想到了dfs。

既然是搜尋,首先我們要畫出來他的搜尋樹,根據搜尋樹方可得到**

因為2265

4 五個元素都需要訪問,並且第乙個元素不一定是最優解

所以我們在搜尋的時候需要補充乙個根節點0!

若不補充根節點0,則每次搜尋都會包含第乙個數字,導致結果可能錯誤!

下面是我畫的搜尋樹,因為該問題不需要每次都把所有的子集用到。

舉乙個例子,本題是要搜尋10,假如是589

64,當搜尋到8的時候不滿足條件

我們就可以直接跳到9,跳到9的前提是前面的數字不滿足條件或者前面的數字已經用了

所以,我們就不需要再去嘗試前面的數字,只需要嘗試我們沒有嘗試過的數字。

所以該搜尋樹會的每一顆子樹可能不等高。

//陣列a[n]代表輸入的子集,用sum判斷是否與s相等,

//k用來計數已經存入陣列中元素的個數

int a[n]

=, sum =

0, k =0;

//用陣列v來存放符合條件的子集

int v[n]=;

//flag判斷是否已經找到滿足條件的子集

bool flag =

false

;void

dfs(

int x)

for(

int i = x +

1; i <= n; i++

)//如果找到了,立馬返回,否則可能會輸出冗雜內容

else

return;}

}int

main()

//這裡進行判斷,防止超時。

if(temp < s)

//從根節點0開始訪問!

dfs(0)

;if(flag)

}else

cout <<

"no solution!"

<

return0;

}

子集和問題

題目描述 子集和問題的乙個例項為 s,t 其中,s 是乙個正整數的集合,c是乙個正整數。子集和問題判定是否存在s的乙個子集s1,使得s1中的各元素之和等於c。題目出自 計算機演算法設計與分析 第3版 王曉東 思路 用回溯法解這道題,我本來想修改排列樹使之可以求出乙個集合的所有子集。但是分析了一下,時...

子集和問題

問題描述 子集和問題的乙個實力為。其中,s 是乙個正整數的集合,c是乙個正整數。判定是否存在s的乙個子集s1使得s1的和為c。輸入 輸入含多組測試用例!對每組測試用例,第一行有兩個正整數n和c,n表示s的大小,c是子集和的目標值。接下來的一行,有n個正整數 1 n 10000 表示集合s中的元素。當...

子集和問題

今天程式考試受挫,遂打算寒假空閒時間刷刷題,練練手感。今天有一題是這樣的,檔案 data.txt 有n 1行,每一行都為乙個正整數,第一行為n,剩餘n行為任意n個正整數。對於正整數m m 2 輸出m個數的和,要求和不大於100,並列出表示式 並且要求表示式不相同。若表示式中的元素相同則表示式就相同,...