Week3 作业 A - 选数问题

问题描述:

n个数,选k个,要求这k个数的和是s,问有几种可行方案

思路:

直接DFS即可,注意边界和可行性剪枝。

总结:

可行性剪枝:当 选的数的个数大于k个、选的数的和大于s、选了k个数但和小于s、选了和为s的数但个数小于k ,这些情况都不必再继续搜索。

代码:

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>
 4 #include <cstring>
 5 using namespace std;
 6 int n,k,s,ans;
 7 int a[100005];
 8 //num表示从a[num]-a[n]中选数,existed表示已经选了existed个数,sum是这些数的和 
 9 void dfs(int num,int existed,int sum) 
10 {
11     if( existed==k && sum==s ) ans++;
12     else if( existed>=k || sum>=s ) return;
13     
14     for(int i=num;i<=n;i++)   //从a[num]-a[n]中选数
15         dfs(i+1,existed+1,sum+a[i]);  //尝试选a[i]
16 }
17 int main()
18 {
19     int T; cin>>T;
20     while(T--)
21     {
22         scanf("%d %d %d",&n,&k,&s);
23         memset( a,0,sizeof(a) );
24         for(int i=1;i<=n;i++)
25             scanf("%d",a+i);
26         ans=0;
27         dfs(1,0,0);
28         cout<<ans<<endl;
29     }
30 }

 

posted @ 2020-03-06 12:12  菜鸡今天学习了吗  阅读(143)  评论(0编辑  收藏  举报