WEEK3 周记 作业A题——深度优先搜索_选数问题

本文介绍了一种使用深度优先搜索(DFS)算法解决选数问题的方法,具体是在n个正整数中找到K个数使它们的和等于给定的sum。文章详细解释了DFS算法的实现过程,包括如何通过剪枝操作优化时间效率,以及完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

WEEK3 周记 作业A题——深度优先搜索_选数问题

一、题意

1.简述

n个正整数,找出K个数使得其和为sum。问能够找出多少个这样的数对。

2.输入格式

第一行输入T<=100,表示多少组测试数据。
对于每一组有两行,第一行输入n、K、S,第二行输入n个正整数。

3.输出格式

对于每一组在一行中输出答案。

4.样例

Input

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

Output

4

注释

k<=n<=16,并且所有的正整数都能用int表示。

二、算法

主要步骤

可以k次循环,但是显然161616^{16}1616是要超时的。


那就优化,采用dfs搜索的思想,也是求所有kkk个数组合的算法思想。
首先我们将得到的整数序列排序。然后进入递归函数。
利用递归,每层递归循环遍历整数序列,每次循环确定一个数,当这个数加上sumsumsum小于等于SSS时,就进入下一层递归。需要注意的是,下一层递归的循环遍历要从上一层确定的数的后一个开始,这样就能避免从头开始再去遍历前面已经经过的数。当递归深度为i=Ki=Ki=Ksum=Ssum=Ssum=S时,这个时候我们就找到了一个满足条件的KKK元数对,之后回到上一层继续执行。

这样实际上是通过剪枝操作来优化了时间效率。

三、代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int pn[20];
int n,K;
/*long long*/ int S;
int cnt; 
int sn[20];
void solve(int i,/*long long*/ int sum,int pos)
{//i是参与构成参数中sum的整数的个数 
	if(i>K) return;
	if(sum==S&&i==K) 
	{
		cnt++;
		return;
	}
	int j;
	for(j=pos;j<n;j++)
	{
		if((sum+pn[j])<=S)
		{
			sn[j]=1;
			solve(i+1,sum+pn[j],j+1);
		}
		else break;
		sn[j]=0;
	}
}
int main()
{
	int T,i,j;
	scanf("%d",&T);
	for(i=0;i<T;i++)
	{
		cnt=0;
		scanf("%d%d%d",&n,&K,&S);
		for(j=0;j<n;j++)
		{
			scanf("%d",&pn[j]);
			sn[j]=0;
		}
		sort(pn,pn+n);//从小到大排序 
		solve(0,0,0);
		printf("%d\n",cnt); 
	}
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值