2017 校招题幸运袋子(递归回溯法 DFS)

一个袋子里面有n个球,每个球上面都有一个号码(拥有相同号码的球是无区别的)。如果一个袋子是幸运的当且仅当所有球的号码的和大于所有球的号码的积。
例如:如果袋子里面的球的号码是{1, 1, 2, 3},这个袋子就是幸运的,因为1 + 1 + 2 + 3 > 1 * 1 * 2 * 3
你可以适当从袋子里移除一些球(可以移除0个,但是别移除完),要使移除后的袋子是幸运的。现在让你编程计算一下你可以获得的多少种不同的幸运的袋子。

输入描述:

第一行输入一个正整数n(n ≤ 1000)
第二行为n个数正整数xi(xi ≤ 1000)

输出描述:

输出可以产生的幸运的袋子数

示例1

输入

复制

3
1 1 1

输出

复制

2

思路:主要考察了递归回溯法;DFS 以及如何剪枝(这里就需要排序了)

考虑 nums[i]=1 那么肯定就是满足的  sum+1>mul*1;

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int n;
int res;
void dfs(vector<int>&nums, int index, int sum, int mul)
{
	for (int i = index; i<n; i++)
	{
		if (i>index&&nums[i] == nums[i - 1])continue;//去重复;
		sum += nums[i];
		mul *= nums[i];
		if (sum > mul)//只有在sum>mul的时候 res+1;并且往下递归运行;
		{
			res += 1;
			dfs(nums, i + 1, sum, mul);
		}
		else //否则的直接退出就是了;后面的数都是大的数 肯定不会成立了;因为已经排过序了;
			break;
		sum -= nums[i];
		mul /= nums[i];

	}
	return;
}
int main()
{
	cin >> n;
	vector<int>nums(n);
	for (int i = 0; i < n; i++)
		cin >> nums[i];
	sort(nums.begin(), nums.end());
	res = 0;
	if (nums[0] == 1)//如果是第一位数等于1的时候 肯定是满足的;直接从后面的点开始;
		dfs(nums, 1, 1, 1);
	dfs(nums, 0, 0, 1);
	cout << res << endl;
}

猜你喜欢

转载自blog.csdn.net/langxue4516/article/details/81708559