题意
Given n positive numbers, ZJM can select exactly K of them that sums to S. Now ZJM wonders how many ways to get it!
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, n 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
思路
选数问题类似于求子集问题,采用递归的写法,每一次递归有两个分支,一个是选中这个数,另一个是不选这个数,递归的结束条件为,选中的数的个数(count1)为K,且选中的数的和(sum)为S,此时记录满足条件的数的组合的计数器加一。为了减少复杂度,有三种情况可以直接返回:
- count>=k&&sum!=s;
- count!=k&&sum==s;
- sum!=s&&i>=n-1(i为下脚标,n为数组元素的个数)
代码
#include<cstdio>
#include<iostream>
using namespace std;
void select(int&, int, int, int, int*);
int n, k, s;
int main()
{
int T;
cin >> T;
for (int j = 0; j < T; j++)
{
cin >> n >> k >> s;
int count=0, * num = new int[n];
for (int i = 0; i < n; i++)
cin >> num[i];
select(count, 0, 0, 0, num);
cout << count << endl;
}
return 0;
}
void select(int& count, int i, int count1, int sum, int* num)
{
if (count1 == k && sum == s)
{
count++;
return;
}
else if ((count1 >= k && sum != s) || (sum == s && count1 != k) || sum > s || i > n - 1)
return;
select(count, i + 1, count1 + 1, sum + num[i], num);
select(count, i + 1, count1, sum, num);
}