深度优先搜索(dfs)基础篇之二,选数

题目描述
给定整数a1、a2、…an,判断是否可以从中选出若干数,使它们的和恰好为K。

输入
首先,n和k,n表示数的个数,k表示数的和。
接着一行n个数。
(1<=n<=20,保证不超int范围)

输出
如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”

样例输入
4 13
1 2 4 7
样例输出
YES
2 4 7


这是一道简单的深度优先搜索算法题,因为 n<=20,所以容易想到暴力法,但是这道题并没有说明组合数的个数,也就是说可以是1个数符合,也可以3个4个数符合,这样我们写for循环时,时间复杂度就会很高,很难通过OJ。
使用深度搜索,递归会把所有情况都考虑在内,只需要写dfs函数就可以搞定。
直接上代码!

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
int n,sum;
int s=0,f=0;
int a[30],b[30];
void dfs(int x)
{
    int i,k;
    if(s>=sum)			//还是老样子,函数需要先写结束条件,判断是否结束
    {			//这道题里当s大于条件和时,就没必要再进行递归了,直接进行判断
        if(s==sum)			//当s等于条件和
        {
            if(f==0)	//f是判断时候有符合条件的输出,当没有符合的时,f始终为0
                f=1;
            if(f)
            {				//符合条件,输出
                printf("Yes\n");
                for(i=0; i<n; i++)		//所有数的下表
                {
                    if(b[i])				//利用数组b判断是否需要输出
                        printf("%d ",a[i]);
                }
                printf("\n");
            }
        }
    }
    for(k=x; k<n; k++)		
    {
        s=s+a[k];		//当前元素,加和  s
        b[k]=1;			//当前元素的下标,在数组b中标记为1
        dfs(k+1);		//进入下个dfs
        s=s-a[k];		//回溯,减去加上的元素
        b[k]=0;			//回溯,把数组b中标记的1返回为0,以便于下次dfs使用
    }
}
int main()
{
    int i,j,k;
    memset(b,0,sizeof(b));		//把数组b全部设为0,便于标记
    scanf("%d %d",&n,&sum);
    for(i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
    }
    dfs(0);							//从第一个数进入dfs
    if(f==0)				//此时递归结束,如果f仍为0,则说明没有符合条件的组合
        printf("No\n");		
        return 0;
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
深度优先搜索DFS)是一种在图或树中遍历所有节点的算法。其基本思想是从起点开始,沿着一条路径一直走到底,直到无法继续为止,然后回溯到上一个节点,再沿着另一条路径继续走到底,直到所有节点都被访问过为止。DFS使用栈(递归)来存储待处理节点,每个节点仅被访问一次。处理一个节点时,先访问它的一个未被访问的相邻节点,若不存在这样的节点则回溯到上一层节点。DFS算法复杂度为O(V+E),V为节点数,E为边数。 以下是一个Python实现的DFS算法的例子: ```python # 定义一个图的类 class Graph: def __init__(self, graph_dict=None): if graph_dict is None: graph_dict = {} self.__graph_dict = graph_dict # 添加节点 def add_node(self, node): if node not in self.__graph_dict: self.__graph_dict[node] = [] # 添加边 def add_edge(self, edge): edge = set(edge) (node1, node2) = tuple(edge) if node1 in self.__graph_dict: self.__graph_dict[node1].append(node2) else: self.__graph_dict[node1] = [node2] # 获取所有节点 def get_nodes(self): return list(self.__graph_dict.keys()) # 获取所有边 def get_edges(self): edges = [] for node in self.__graph_dict: for neighbour in self.__graph_dict[node]: if {neighbour, node} not in edges: edges.append({node, neighbour}) return edges # 定义DFS算法 def dfs(self, start_node): visited = set() self.__dfs(start_node, visited) def __dfs(self, node, visited): visited.add(node) print(node, end=' ') for neighbour in self.__graph_dict[node]: if neighbour not in visited: self.__dfs(neighbour, visited) ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值