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

A-选数问题

Description

给定n个正整数,选择他们其中的K个数总和是S,要求输入n,K,S,输出有多少种不同的选择。

Sample

input:
1
10 3 10
1 2 3 4 5 6 7 8 9 10
output:
4

Idea

首先我使用了list存放被选中的数,方便加入元素、去除元素,也可以时刻知道选中的个数。运用递归进行有选择的枚举,对于每个数来说,分别考虑选中它和不选它的情况,每加入一个元素就对sum减去相应的值,当list个数等于K并且sum恰好等于0时即是符合条件的一种解,而当list个数超过K或sum已经小于0时及时返回不再进行这种情况下的递归。

Summary

基本思想是枚举,进行全排列,依次判断每个子集是否满足要求。为了降低复杂度,要有选择地进行枚举,很多显然不成立的情况直接跳过,比如子集元素个数超过K、子集元素和超过S,当出现符合条件的解及时返回,因为再往下递归加入元素也必然不符合条件。

Codes

#include <iostream>
#include <list>
using namespace std;
int a[16];
int t,n, k, s;
int amount = 0;
void solve(int i,int sum,list<int> &res) {
	if (res.size()==k&&sum == 0) { amount++; 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()
{
	cin >> t;
	while (t--)
	{
		amount = 0;
		scanf("%d%d%d", &n, &k, &s);
		memset(a, 0, sizeof(int));
		for (int i = 0; i < n; i++)
			cin >> a[i];
		list<int> r;
		solve(0, s, r);
		printf("%d\n", amount);

	}
}


发布了21 篇原创文章 · 获赞 5 · 访问量 786

猜你喜欢

转载自blog.csdn.net/weixin_44578615/article/details/104711472