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;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
递归回溯法是一种经典的算法思想,通常用于解决搜索问题、组合问题、排列组合问题等。其基本思想是从某一点开始,按照一定的规则向前搜索,若搜到某一步无解,则回退到上一步继续搜索,直到找到问题的解。 递归回溯法的基本框架如下: ```python def backtrack(路径, 选择列表): if 满足结束条件: 记录结果 return for 选择 in 选择列表: 做出选择 backtrack(路径, 选择列表) 撤销选择 ``` 其中,路径表示当前搜索路径,选择列表表示当前可选的选择列表。接下来,我们以求解全排列问题为例,具体介绍一下递归回溯法的实现过程。 全排列问题:给定一个字列表,求出其所有可能的排列。 具体代码实现如下: ```python def permute(nums): res = [] def backtrack(path, choices): if not choices: res.append(path) for i in range(len(choices)): backtrack(path+[choices[i]], choices[:i]+choices[i+1:]) backtrack([], nums) return res ``` 其中,path表示当前搜索路径,choices表示当前可选的选择列表(即未被选择过的字列表),如果当前选择列表为空,说明已经搜索到底部(即满足结束条件),将当前路径记录到结果中。否则,从选择列表中选择一个字,将其加入到当前路径中,然后继续递归搜索,最后将选择撤销,回溯到上一步。 使用方法如下: ```python nums = [1, 2, 3] res = permute(nums) print(res) ``` 输出结果为: ``` [[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]] ``` 以上就是递归回溯法的基本实现方法,可以根据具体问题的特点进行相应的修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值