题目描述:
Given n positive numbers, you can select exactly K of them that sums to S. Now you wonder 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.
sample input and output:
Input:
1
10 3 10
1 2 3 4 5 6 7 8 9 10
Output:
4
others:Remember that k<=n<=16 and all numbers can be stored in 32-bit integer.
个人思路:
按照我的变量。题目的大体意思是:从n个数里面选出k个和为s的数。
因为用的是DFS,所以主要是通过递归来实现的。递归从i = 0开始,也就是从第一个数开始,如果递归没结束,接下来就分两步,第一步将第i+1个数作为第一个数继续,第二步是选择第i个数作为k个数中的第一个。
然后就是递归出口的设计:有三个,第一个是符合题意的时候;第二个是当i超过了n的时候;第三个是当选的数的个数超过了k或者选数的和超过了s;
代码实现:
#include<iostream>
using namespace std;
int n, k, s;
int num[1000];
int res_num ;//组数
int s_num;//已选数的个数
void select_num(int i, int sum) {
if (s_num == k && sum == 0) {
res_num++;
return;
}
if (i >= n)return;
if (s_num > k || sum < 0)return;
select_num(i + 1, sum);//不选,下一个
s_num++;//选num[i]
select_num(i + 1, sum - num[i]);//选,sum减掉num[i]
s_num--;//不行就-掉
}
int main() {
int m;
cin >> m;
for (int p = 0; p < m; ++p) {
res_num = 0;//initial
num[1000] = { 0 };
s_num = 0;
cin >> n >> k >> s;
for (int j = 0; j < n; ++j)
cin >> num[j];
select_num(0, s);
cout << res_num << endl;
}
return 0;
}