Week3作业A-选数问题

1. 题意

给定n个正整数,要求选出k个数,使得选出来的k个数的和为s,输出方案的种数。

2.样例

Sample Input
第一行输入数据组数
第二行输入n,k,s
第三行输入n个正整数
Sample Output
输出方案数目
在这里插入图片描述

3.解题思路

分析:
  1.这是一个典型的子集枚举问题,可以列举所有子集判定是否合法,但复杂度高。
  2.进行优化,即可行性剪枝,排除一些不合法的情况减少枚举次数,即排除选的数目超过了k,选的数的总和超过了sum。

4.总结

1.对于此类题目,我们要考虑怎样将数据进行优化,进行可行性剪枝或优化剪枝
2.对于本题,我采用vector进行存储数据,所以每进行一组数据后要将vector清空处理
3.对于此题枚举,很像枚举中的位向量法,对于每个子集,两种状态要么选中,要么没选中,枚举每一个位置的状态,可以得到各种子集

void s(int i,vector<int> &res)
{
	if(i==n)
	{
		for(int i=0;i<res.size();i++)
		{
			cout<<res[i]<<" "
		}
		cout<<endl;
		return;
	}
	s(i+1,res);
	res.push_back(v[i]);
	s(i+1,res);
	res.pop_back();
}

5.AC代码

#include<iostream>
#include<vector>
using namespace std;
int n,k,count=0,sum;
vector<int> v;
void dfs(int i,int sum,vector<int> &res)
{
	if(res.size()==k&&sum==0)
	{
		count++;
		return ;
	}
	if(i>=n||res.size()>k||sum<0) return;
	dfs(i+1,sum,res);
	res.push_back(v[i]);
	dfs(i+1,sum-v[i],res);
	res.pop_back();
}
int main()
{
	int m,k2;
	cin>>k2;
	for(int j=0;j<k2;j++)
	{
		vector<int>v1;
		cin>>n>>k>>sum;
		for(int i=0;i<n;i++)
		{
			cin>>m;
			v.push_back(m);
		}
		dfs(0,sum,v1);
		cout<<count<<endl;
		while(v.size()!=0)
		{
			v.pop_back();
		}
		count=0;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值