题目:
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.
思路:
这一题的主要思路为dfs,即暴力枚举所有可能的情况,但需要做出一定的剪枝,在判断符合条件的情况下计数即可。这里我设计dfs函数的思路为对给定数据逐个判断是否选中,若选中则加入链表,且每对数据判断一次都要做以下判断:确认当前链表内数据个数是否超过题目给定个数,超过则回溯;确认链表内数据和是否大于题目需求和,大于则回溯;查看是否将给定数据判断完毕,判断完毕则回溯;若链表元素数及元素总和与题目给定相等,此时计数器加一,回溯。当该流程执行完毕后,计数器内得到的数就是最后的方案数。
代码:
#include <iostream>
#include <list>
#include <map>
using namespace std;
int k;int n;int s;int count=0;
int a[17];
map<list<int>,int> m;
void choose(int i,int sum,list<int> &li)
{
if(li.size()==k&&sum==s/*&&m[li]==0*/)
{
count++;
m[li]=1;
return;
}
if(i>n||sum>s) return;
if(li.size()>k) return;
choose(i+1,sum,li);
li.push_back(a[i-1]);
choose(i+1,sum+a[i-1],li);
li.pop_back();
return;
}
int main()
{
int t;
cin>>t;
list<int> li;
for(int i=0;i<t;i++)
{
cin>>n>>k>>s;
for(int j=0;j<n;j++)
cin>>a[j];
choose(1,0,li);
cout<<count<<"\n";
count=0;
li.clear();
}
}