DFS深度优先搜索刷题(一)

news2024/9/24 6:08:06

一.P2089 烤鸡

算法思想: 指数型枚举,可以通过dfs深度优先搜索暴力枚举出所有可能的情况,在通过剪枝去除错误的方案来减少时间开销。主要用一个循环枚举每个调料放几克(每个位置的分支情况都相同),注意回溯时当前位置的置空。

#define N 15
int n;
int arr[N];//存临时方案
int mem[50000][N];//存正确的方案
int res = 0;//存方案数
//表示枚举到了第x位,sum表示此时调料的质量和
void dfs(int x, int sum)
{
    //sum不符,剪枝
    if (sum > n)
        return;
    //枚举完第10位后判断是否符合
    if (x > 10)
    {
        if (sum == n)
        {
            res++;
            for (int i = 1; i <= 10; i++)
            {
                mem[res][i] = arr[i];
            }
        }
        return;
    }
    for (int i = 1; i <= 3; i++)
    {
        //记录第x位上的调料质量
        arr[x] = i;
        dfs(x + 1, sum + i);
        //回溯,将调料质量置空
        arr[x] = 0;
    }
}

二.P1088 [NOIP2004 普及组] 火星人

 

算法思想: 排序型枚举,依旧dfs暴力枚举出每种排序,主要通过st[N]状态数组来记录每个数的选择情况,第x位选择状态为未选择的数并给该数设置已选择状态,然后枚举x+1位直至枚举完,判断是否符合,并根据具体情况进行剪枝。

#define N 10010

int n, a;
int mas[N];//存火星人初始值
int arr[N];//存符合条件的
bool st[N];//存每个数的状态
int cnt = 0;//记录增加的值
bool return0 = false;

//枚举到第x位
void dfs(int x)
{
    //剪枝
    if (return0)
    {
        return;
    }

    if (x > n)
    {
        cnt++;//初始值的cnt为1,则cnt为a+1时表示加上a后的排序
        if (cnt == a + 1)//注意是a+1!!!
        {
            return0 = true;//表示已经找到,直接使剩下的递归全部剪枝
            for (int i = 1; i <= n; i++)
            {
                printf("%d ", arr[i]);
            }
            printf("\n");
        }
        return;
    }
    //第x位上的手指不能枚举到已经存在于其他位置的手指(序号)
    for (int i = 1; i <= n; i++)
    {
        if (!cnt)
        {
            //使一开始从火星人初始值开始深搜
            i = mas[x];
        }
        //判断代号i的手指是否被选过
        if (!st[i])
        {
            st[i] = true;//表示第x位选i代号的手指,状态置为true,防止其他位置再次选择i;
            arr[x] = i;//存临时方案
            dfs(x + 1);//枚举下一位置
            arr[x] = 0;//回溯置空
            st[i] = false;//回溯重置i代号手指的状态,使其他位置可以选择i;
        }

    }
}

int main()
{
    scanf("%d %d", &n, &a);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &mas[i]);
    }
    dfs(1);

    return 0;
}

三.P1149 [NOIP2008 提高组] 火柴棒等式

算法思想:指数型枚举,一共三个位置,先构造一个火柴用量数字表,根据表依次枚举每个位置的火柴表示数,最后符合火柴用量==n,数字等式成立两个条件后记录数+1,注意当火柴用量超出时剪枝。

#define N 1000

int firecout[N] = { 6,2,5,5,4,5,6,3,7,6 };//记录每个数所用火柴个数
int n;//可用的火柴总数
int res = 0;//记录方案数
int arr[10];//记录临时方案

//枚举到第x位,sum记录此时所用火柴数
void dfs(int x, int sum)
{
    if (sum > n) return;
    if (x > 3)
    {
        //枚举完三位后判断火柴等式是否成立
        if (arr[1] + arr[2] == arr[3]&& sum == n)
            res++;
        return;
    }
    for (int i = 0; i < N; i++)
    {
        //记录第x位的火柴表示数,便于最后的条件判断
        arr[x] = i;
        dfs(x + 1, sum + firecout[i]);
    }
}

int main()
{
    scanf("%d", &n);
    n -= 4;
    //记载个位数以外的数的所用火柴数
    for (int i = 10; i <= N; i++)
        firecout[i] = firecout[i / 10] + firecout[i % 10];
    dfs(1, 0);
    printf("%d", res);
    return 0;
}

 四.P1036 [NOIP2002 普及组] 选数

算法思想:组合型枚举,用dfs暴力枚举出所有组合情况,主要是通过设置一个start下标,使第x位以后的位置都不能枚举到start下标以前的数据,实现组合不重复的实现。通过算出x位以后可选的数是否最终能达到要求来剪枝。

#define N 25
int n, k;
int _begin[N];//存初始数组
int choice[N];//存临时选择数组
int res = 0;//存方案数

bool isPrimenum(int n)
{
    if (n < 2) return false;
    for (int i = 2; i <= n / i; i++)
    {
        if (n % i == 0)
            return false;
    }
    return true;
}
//x为枚举到的位置,start为选择初始数的位置(选组合数)
//start前的数,第x位及其以后的位都不会选到(避免重复)。
void dfs(int x, int start)
{
    //剪枝,x-1为已选位置的个数,n-start+1为剩下的可选个数
    if (x - 1 + n - start + 1 < k) return;
    if (x > k)
    {
        //已选k个数的和判断是否为质数(判断结果)
        int sum = 0;
        for (int i = 1; i <= k; i++)
        {
            sum += choice[i];
        }
        if (isPrimenum(sum))
        {
            res++;
        }
        return;
    }
    //组合型枚举的核心,第x位从start开始,保证组合不重复
    for (int i = start; i <= n; i++)
    {
        choice[x] = _begin[i];//存第x位的数
        dfs(x + 1, i + 1);//开始选择第x+1位的数
        choice[x] = 0;//回溯置空
    }
}

int main()
{
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &_begin[i]);
    }
    dfs(1, 1);//从第1位开始枚举
    printf("%d", res);
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1539462.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测

分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测 目录 分类预测 | Matlab实现PSO-KELM粒子群优化算法优化核极限学习机分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.MATLAB实现PSO-KELM粒子群优化算法优化核极限学习机分类预测(完整源…

【c++初阶】C++入门(下)

✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅ ✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨ &#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1f33f;&#x1…

lvgl 窗口 windows lv_port_win_visual_studio 版本 已解决

不知道的东西&#xff0c;不知道lvgl窗口。一切从未知开始 lv_port_win_visual_studio 主分支 对应的分支 v7版本更新git submodule update --init --recursive同步 lvgl代码随后打开 visualSudio 打开.sln 文件 编译 release模式 允许 一切正常代码部分

iOS应用审核问题解决方案及优化方法 ✨

摘要 本文将针对iOS应用提交审核时可能遇到的问题&#xff0c;如“你必须在Xcode中添加com.apple.developer.game-center密钥”&#xff0c;以及突然间提交送审报错情况进行探讨。通过大量查询资料和尝试&#xff0c;结合案例分析&#xff0c;提供了解决方案和优化方法&#x…

Linux进程地址空间详解

文章目录 前言一、程序地址空间二、感受虚拟地址的存在三、进程地址空间四、程序从磁盘加载到内存的过程4.1 物理地址和虚拟地址的区别 五、写时拷贝5.1 解释fork()函数有两个返回值 前言 我们在学习C/C的时候用到的地址是什么地址呢&#xff1f;虚拟地址&#xff1f;物理地址&…

抗疫医疗用品销售平台|基于JSP技术+ Mysql+Java+ Tomcat的抗疫医疗用品销售平台设计与实现(可运行源码+数据库+设计文档)

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 2024年56套包含java&#xff0c;ssm&#xff0c;springboot的平台设计与实现项目系统开发资源&#xff08;可…

mysql 如何设计分库分表

在MySQL中设计分库分表的方法通常涉及到水平拆分与垂直拆分两种主要方式。 水平拆分&#xff1a; 按照某一列进行水平拆分&#xff1a; 可以根据某一列&#xff08;如用户ID、时间等&#xff09;的取值范围将数据拆分到不同的数据库或表中。基于哈希值的水平拆分&#xff1a;…

贪吃蛇(C语言超详细版)

目录 前言&#xff1a; 总览&#xff1a; API&#xff1a; 控制台程序&#xff08;Console&#xff09;&#xff1a; 设置坐标&#xff1a; COORD&#xff1a; GetStdHandle&#xff1a; STD_OUTPUT_HANDLE参数&#xff1a; SetConsoleCursorPosition&#xff1a; …

python--循环(作业)

作业一&#xff1a; 判断一个数是否为质数&#xff08;素数&#xff09; flag True prime int(input("请输入一个整数&#xff1a;")) for num in range(2, prime):if prime % num 0:flag Falsebreak if flag:print("它是质数") else:print("它…

2024年阿里云服务器地域和可用区所在地区城市分布表

阿里云服务器地域和可用区有哪些&#xff1f;阿里云服务器地域节点遍布全球29个地域、88个可用区&#xff0c;包括中国大陆、中国香港、日本、美国、新加坡、孟买、泰国、首尔、迪拜等地域&#xff0c;同一个地域下有多个可用区可以选择&#xff0c;阿里云服务器网aliyunfuwuqi…

RabbitMQ问题

如何实现顺序消费&#xff1f; 消息放入到同一个队列中消费 如何解决消息不丢失&#xff1f; 方案&#xff1a; 如上图&#xff1a;消息丢失有三种情况&#xff0c;解决了以上三种情况就解决了丢失的问题 1、丢失1--->消息在到达交换机的时候&#xff1b;解决&#xff1…

unity学习(68)——相机/模型的旋转/位置计算

这个比想象中要难&#xff0c;而且需要自己写。 1.相机可以转xy两个位置&#xff0c;可以点头和转圈。注意这里有一个if判断&#xff08;后面返回来发现了这些问题&#xff09; 2.角色不能点头&#xff0c;只能转圈。 难得是移动方向&#xff0c;因为移动方向(位置)和转向是相…

Spark与flink计算引擎工作原理

Spark是大批量分布式计算引擎框架&#xff0c;scale语言开发的&#xff0c;核心技术是弹性分布式数据集&#xff08;RDD&#xff09;可以快速在内存中对数据集进行多次迭代&#xff0c;支持复杂的数据挖掘算法及图形计算算法&#xff0c;spark与Hadoop区别主要是spark多个作业之…

Mac 搜索工具比对 ProEverything ProFind DFind 等

对比 Windows的everything用习惯了&#xff0c;其他的搜索追之不及啊。Mac上对比了一圈&#xff0c;简单总结一下。 比较项ProEverythingProFindDFindEasyFindScherlokk是否索引方式索引遍历遍历遍历待试用费用收费 推荐88元终身版收费收费免费待试用是否可全盘全盘无法查找影…

pytest简介以及命令行执行

pytest简介以及安装 pytest简介导入第三方库修改工具类 pytest命令方式执行函数执行pytest中的参数详解 pytest简介 pytest有很多强大的插件 pytest-html &#xff08;生成html格式的自动化测试报告&#xff09; pytest-xdist &#xff08;测试用例分布式执行&#xff0c;多cpu…

利用MSF生成php,windows,Linux三类木马

一、什么是msfvenom&#xff1f; msfvenom是msf中的一个独立的负载生成器&#xff0c;它可以利用msf中的payloads和encoders来生成各种格式的木马文件&#xff0c;并在目标机上执行&#xff0c;配合meterpreter在本地监听上线。msfvenom是msfpayload和msfencode的结合体&#x…

基础:TCP四次挥手做了什么,为什么要挥手?

1. TCP 四次挥手在做些什么 1. 第一次挥手 &#xff1a; 1&#xff09;挥手作用&#xff1a;主机1发送指令告诉主机2&#xff0c;我没有数据发送给你了。 2&#xff09;数据处理&#xff1a;主机1&#xff08;可以是客户端&#xff0c;也可以是服务端&#xff09;&#xff0c…

SOPHON算能服务器SDK环境配置和相关库安装

目录 1 SDK大包下载 2 安装libsophon 2.1 安装依赖 1.2 安装libsophon 2 安装 sophon-mw 参考文献&#xff1a; 1 SDK大包下载 首先需要根据之前的博客&#xff0c;下载SDK大包&#xff1a;SOPHON算能科技新版SDK环境配置以及C demo使用过程_sophon sdk yolo-CSDN博客 …

Mysql之索引存储原理

在介绍索引实现之前&#xff0c;我们先来了解下几种树的数据结构&#xff1a; 一、二叉搜索树 二叉搜索树有以下性质&#xff1a; 1.每个节点有一个关键字 2.左右孩子至多有一个。 3.关键字大于左孩子&#xff0c;小于右孩子。 正因为二叉搜索树的特性&#xff0c;所以这种数…