week3 A 選數問題

2021-10-03 19:53:56 字數 1620 閱讀 4079

given n positive numbers, select exactly k of them that sums to s. wonders how many ways to get it!

給n個數,選擇k個數相加的和為s,找出所有數的組合。

the first line, an integer t<=100, indicates the number of test cases. for each case, there are two lines. the first line, three integers indicate n, k and s. the second line, n integers indicate the positive numbers.

一共有t組資料,t<=100,每一組資料讀入n,k,s與n個正數。

運用dfs找出n個數的子集,n個數在某個子集中要麼出現要麼不出現,對應如下:

b.

push_back

(a[i]);

//選入乙個數

dfs(i+

1,sum - a[i]

,k,n,b,a)

;//將和減去選入的數,表示該數選入

b.pop_back()

;//彈出該數

dfs(i+

1,sum,k,n,b,a)

;//和不減,該數不選入

通過當某乙個子集的個數為k個時,判斷它們的和是不是s,當和為s時,即為一組正確答案。

通過剪枝操作來即使停止dfs的搜尋,提高時間效率:1當子集的個數超過k個時可以及時回溯;2當子集的和大於s時回溯

使用vector陣列來存放選入的元素,用vector可以方便判斷出子集中選入的數的個數。

dfs搜尋會向一種條件進行探索,從初始結點搜尋到下乙個結點,當到達某種設定的限定時就會回溯,回到上乙個結點,上乙個結點再選擇另外一種條件進行探索。使用剪枝策略可以判斷當前搜尋的路徑是否合法,發現不合法的條件時可以及時回溯,提高效率。

#include

#include

using namespace std;

int ans;

void

dfs(

int i,

int sum,

int k,

int n,vector<

int>

&b,int a)

if(b.

size()

> k || sum <0)

if(b.

size()

== k && sum ==0)

b.push_back

(a[i]);

dfs(i+

1,sum - a[i]

,k,n,b,a)

; b.

pop_back()

;dfs

(i+1

,sum,k,n,b,a);}

intmain()

vector<

int> b;

dfs(

0,s,k,n,b,a)

; cout<}return0;

}

week3 選數問題

title 有n個正整數,求出有多少種方式,使選取k個數,和為s。input the first line,an integer t 100t 100,indicates the number of test cases.for each case,there are two lines.the f...

week3 作業A題 選數問題 遞迴

這題用遞迴的方法解決,每次都有兩個分支,乙個是選擇這個數,乙個是不選這個數,然後進入下一層,對下乙個數進行判斷,同時在每一步的過程中判斷已選擇的數個數和當前的選擇的數的和,來進行剪枝。先是寫了乙個結構體list,有push back,pop back,size幾個方法 class list void...

Week3 作業A 選數 dfs剪枝

有n個數,從中選取k個,要求和為s,計算有多少種選數的方法。其中,k n 16。dfs遞迴求解,n個數存放在陣列a內,遞迴函式的引數為sum i,表示從a i 向後選數,和為sum,選出的數放進全域性變數vector容器v內。當v中元素數為k並且sum 0時,找到一種符合條件的選數方法 當i n或者...