问题描述
给出n个数,从中选出k个数,使这k个数的和等于sum;
问:有几种选法?
Input
第一行一个整数T<=100,表示测试数据的数目。
每组数据都有两行,第一行三个参数n(给出的数字个数),k(选的数个数),s(sum);第二行为给出的n个数。
Output
每种情况输出一个数字表示不同选法的种数。
Example
input
1
10 3 10
1 2 3 4 5 6 7 8 9 10
Output
4
解题思路
- 本题即从给定的n个数中选出k个数,使和为sum。最简单的方法即列举所有的情况,取符合要求的。但时间、空间复杂度较大。
- 可以把一些不可能符合的情况直接去掉,即剪枝。例如:选的数个数大于k个,sum大于s;
- 所以可以通过dfs按照数组顺序往下遍历,如果选数的次数大于k或者总和大于sum,return;如果次数=k,和=sum,个数+1;否则继续往下dfs数组的下一个元素。
完整代码
#include<iostream>
using namespace std;
int count=0;//用全局变量表示次数
int s,k;
void dfs(int sum,int a[],int n,int begin,int times)
{
if(sum==s&×==k)//达到条件
{count++;return;
}
else if(sum>=s||times>=k)
return;
for(int i=begin;i<n;i++)
dfs(sum+a[i],a,n,i+1,times+1);
}
int main()
{ int n1;
int number;
cin>>n1;
for(int i=0;i<n1;i++)
{cin>>number>>k>>s;
int a[number];
for(int l=0;l<number;l++)
cin>>a[l];
count=0;
dfs(0,a,number,0,0);
cout<<count<<endl;
}
}