week3作业——选数问题

主要思路:
使用递归解决
递归需要记录的信息:

  • 当前选数的位置(从一个数组左端开始逐个选取)
  • 已选的数的和
  • 保存已选数的vector

在即将进入下一重递归时,有两种选择:将当前数字加入、不加入
若不进行剪枝,递归次数(复杂度)会高达 2n
可进行剪枝的地方:

  • 当遍历的给定数组末尾时
  • 当已选数字的个数超过要求时
  • 当已选数字的和超过要求时

在以上三种情况出现时,即时停止即可

A - 选数问题

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.

Sample Input

1
10 3 10
1 2 3 4 5 6 7 8 9 10

Sample Output

4
  • A Possible Solution
#include<stdio.h>
#include<vector>
using namespace std;

int a[20], n, K, S, cnt;
vector<int> v;

void solution(int cur_num, int cur_sum, vector<int>& res) {
	if (res.size() == K && cur_sum == S) {
		cnt++;
		return;
	}
	if (cur_num >= n)return;
	if (v.size() > K || cur_sum > S)return;

	solution(cur_num + 1, cur_sum, res);
	res.push_back(a[cur_num]);
	solution(cur_num + 1, cur_sum + a[cur_num], res);
	res.pop_back();
}
int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		cnt = 0;
		scanf("%d %d %d", &n, &K, &S);
		for (int i = 0; i < n; i++)
			scanf("%d", &a[i]);
		solution(0, 0, v);
		printf("%d\n",cnt);
	}
	return 0;
}
发布了11 篇原创文章 · 获赞 0 · 访问量 130

猜你喜欢

转载自blog.csdn.net/weixin_43669888/article/details/104810417