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 }