码迷,mamicode.com
首页 > 其他好文 > 详细

dfs之选数问题

时间:2020-03-14 12:52:39      阅读:49      评论:0      收藏:0      [点我收藏+]

标签:line   多少   stream   http   数据   pos   NPU   strong   turn   

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之选数问题

标签:line   多少   stream   http   数据   pos   NPU   strong   turn   

原文地址:https://www.cnblogs.com/liuzhuan-xingyun/p/12491256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!