dfs之选数问题

Posted liuzhuan-xingyun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dfs之选数问题相关的知识,希望对你有一定的参考价值。

Problem

给定n个正数,从中选出K个来使得他们的和为S,请问一共有多少种方法?

 

Input:

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, nn integers indicate the positive numbers.

Output

For each case, an integer indicate the answer in a independent line.

 

Example

Input
1
10 3 10
1 2 3 4 5 6 7 8 9 10
Output
4

解题思路:

数据结构:

题面很直观,只需要用到简单的数组即可。

算法:dfs

一、很容易想到的便是暴力枚举,即找集合的子集使得子集元素之和为给定值,复杂度为O(K·2^n)

二、再简单思考我们会发现

对于给定的元素有两种状态,要么选,要么不选,由于我们只选出k个即可,当选择了某个元素,问题就可以化解为求剩下的集合里面和为sum-该元素的k-1子集数目,一步一步递归下去、、、最后问题(可行)的终点为0个元素、和为0这样一个问题。//相当于组合问题的一个优化

 

Code:

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 int n,S,K,methods=0;
 6 int *ar;
 7 
 8 void dfs(int from,int sum,int num){
 9     if(sum<0||num<0)
10         return ;
11     
12     if(num==0){
13         if(sum==0){
14             methods++;
15             return ;
16         }
17         else
18            return ;
19     }
20     else{
21         for(int i=from+1;i<=n;i++)
22          dfs(i,sum-ar[i-1],num-1);
23     }        
24 }
25 
26 int main(){
27     int T;
28     cin>>T;
29     cin>>n>>K>>S;
30     while(T--){
31         ar = new int[n];        
32         for(int i=0;i<n;i++)
33             cin>>ar[i];
34         sort(ar,ar+n);
35         dfs(0,S,K);
36         cout<<methods<<endl;
37         
38         methods=0;        
39         if(T==0)
40         //exit(0);
41           return 0;
42                     
43         cin>>n>>K>>S;
44     }
45     return 0;
46 } 

 

以上是关于dfs之选数问题的主要内容,如果未能解决你的问题,请参考以下文章

DFS-选数

DFS-选数

DFS-选数

P1036选数

洛谷 P1036 选数背包型DFS/选or不选

P1036 选数