程序设计思维与实践 Week3 作业A - 选数问题

题意

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;
 } 
发布了4 篇原创文章 · 获赞 0 · 访问量 210

猜你喜欢

转载自blog.csdn.net/qq_45337415/article/details/104825258
今日推荐