题意
Given nn positive numbers, ZJM can select exactly KK of them that sums to SS. Now ZJM wonders how many ways to get it!
Input
The first line, an integer T<=100T<=100, indicates the number of test cases. For each case, there are two lines. The first line, three integers indicate nn, KK and SS. The second line, nn integers indicate the positive numbers.
Output
or 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
思想
首先,此题需要输出方案,所以数据量一定不大,对于每个数来说有两种可能1:被选;0:不被选,利用dfs解决此类问题,dfs搜索每一个数,判断其选或不选,可以枚举所有子集判断是否合法,此时复杂度为O(K*2^n),但这里面有很多显然不合法的情况:1)选的数的个数超过了 K; 2)选的数的和超过了 sum;所以合理剪枝,人为判断什么情况下必定无解,避免dfs搜索无解。
总结
课堂例题,利用dfs,注意合理剪枝即可。
代码
#include <iostream>
#include <list>
#include <string.h>
using namespace std;
list <int>test;
int a[20];
int count=0;
int n,k,s;
void solve(int i,int sum,list<int>&res)
{
if(res.size()==k&&sum==0)
{
count++;
return ;
}
if(i>=n) return;
if(res.size()>k||sum<0) return;
solve(i+1,sum,res); //不选
res.push_back(a[i]);
solve(i+1,sum-a[i],res);//选
res.pop_back();
}
int main()
{
int t;
cin>>t;
for(int i=0;i<t;i++)
{
cin>>n>>k>>s;
count=0;
for(int j=0;j<n;j++)
{
cin>>a[j];
}
solve(0,s,test);
cout<<count<<endl;
memset(a,0,sizeof(a));
}
return 0;
}