迭代加深——AcWing 170. 加成序列

迭代加深

定义

迭代加深搜索(Iterative Deepening Depth-First Search, IDS)是一种结合了深度优先搜索(DFS)和广度优先搜索(BFS)特点的算法。它通过限制搜索树的深度来控制搜索范围,起初以较小的深度限制进行搜索,如果没有找到解,则逐渐增加深度限制,重复搜索过程,直到找到解为止。这种方法既保留了DFS的空间效率(因为它不需要像BFS那样一次性生成所有深度级别的节点),又具有BFS的“全面性”(最终能找到解,如果存在的话),同时还能有效避免陷入深度过大的搜索分支。

运用情况

迭代加深搜索特别适用于那些有深度限制或者不知道最优解深度的问题,如棋盘游戏(如骑士巡逻问题)、迷宫探索、最短路径查找(特别是在有界情况下)等。它在处理存在解但深度未知,且深度较深的情况下,比普通DFS更有效率,因为后者可能会陷入深度过大的分支而无法及时找到解。

注意事项

  1. 深度限制:每次迭代时都需要设定一个深度限制,随着迭代次数增加,深度限制也随之增加。
  2. 剪枝:在搜索过程中要有效利用剪枝技术,比如基于限界函数的剪枝,避免无效的深度探索。
  3. 记忆化:虽然不是必须的,但使用记忆化技术(记录已访问状态)可以显著减少重复计算,提升效率。
  4. 资源管理:由于深度逐步增加,需要注意控制内存使用,避免栈溢出等问题。

解题思路

  1. 初始化:设置初始深度限制d=1,记录已访问状态(如果有记忆化需求)。
  2. 循环迭代:在一个循环中,执行以下步骤直到找到解:
    • 深度受限DFS:使用深度限制d进行深度优先搜索。在搜索过程中,如果到达叶子节点且满足目标条件,则找到了解,结束搜索。
    • 未找到解:如果当前深度的搜索没有找到解,则增加深度限制d=d+1,继续下一轮迭代。
  3. 退出条件:当达到某个预设的最大深度或者找到解时,结束迭代。
  4. 优化:在搜索过程中,利用剪枝策略减少不必要的探索,如基于深度的剪枝、基于代价的剪枝等。

迭代加深搜索的核心优势在于它能够逐步扩大搜索范围,同时保持了良好的空间效率和逐步接近最优解的能力,非常适合于那些深度未知但有界的问题场景。

AcWing 170. 加成序列

题目描述

170. 加成序列 - AcWing题库

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

int n;
int path[N];

bool dfs(int u, int k)
{
    if (u == k) return path[u - 1] == n;

    bool st[N] = {0};
    for (int i = u - 1; i >= 0; i -- )
        for (int j = i; j >= 0; j -- )
        {
            int s = path[i] + path[j];
            if (s > n || s <= path[u - 1] || st[s]) continue;
            st[s] = true;
            path[u] = s;
            if (dfs(u + 1, k)) return true;
        }

    return false;
}

int main()
{
    path[0] = 1;
    while (cin >> n, n)
    {
        int k = 1;
        while (!dfs(1, k)) k ++ ;

        for (int i = 0; i < k; i ++ ) cout << path[i] << ' ';
        cout << endl;
    }

    return 0;
}

代码思路

  1. 初始化与输入:定义了一个全局变量path[N]来存储当前搜索到的序列,初始化path[0]=1,然后不断读入整数n,直到输入为0停止。
  2. 深度优先搜索:定义了dfs(u, k)函数,其中u代表当前正在尝试填充序列的位置,k是序列期望的最大长度。该函数试图从位置u开始构建序列,如果成功构建到长度为k且最后一个元素为n的序列,则返回true
    • 对于每个位置u,遍历所有可能的前两个元素组合(i, j),计算它们的和s,并检查s是否适合作为path[u](即不大于n,不在序列中出现过,且大于path[u-1])。
    • 如果找到合适的s,则标记s为已使用,并继续递归搜索下一个位置。
  3. 主循环:从长度为2的序列开始尝试,不断增加序列长度k,直到找到满足条件的序列为止。

改进思路

  1. 剪枝优化:原代码中每次搜索都会重新初始化st[N]数组,这是一个不必要的开销。可以在外部定义并重用该数组,仅在每次搜索开始前清零。
  2. 减少重复计算:在搜索过程中,可以通过记录并检查之前已经尝试过的和来避免重复计算,进一步优化搜索效率。
  3. 优化搜索起点:考虑到序列的构造特性,搜索时可以从上次成功的位置继续,而不是每次都从头开始。

改进代码

#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 110;

int n, k;
int path[N];
bool st[N];

bool dfs(int u)
{
    if (u == k) return path[u - 1] == n;

    for (int i = u - 1; i >= 0; i--) 
        for (int j = i; j >= 0; j--) 
        {
            int s = path[i] + path[j];
            if (s > n || s <= path[u - 1] || st[s]) continue;
            st[s] = true;
            path[u] = s;
            if (dfs(u + 1)) return true;
            st[s] = false; // 回溯
        }

    return false;
}

int main()
{
    while (cin >> n, n)
    {
        k = 1;
        memset(st, false, sizeof st);
        path[0] = 1;
        
        while (!dfs(1)) k++; // 直接在循环中增加k,直到找到解

        for (int i = 0; i < k; i++) cout << path[i] << ' ';
        cout << endl;
    }

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CTFShow的RE题(一)

RE2 1.中文字符的显示 2.对文件的读取操作 3.RC4加密 &#xff08;有一点是魔改的&#xff09; 4.enflag.txt文件里面的密文是ASCII编码之后的数据(可以放ida中) 也可以放到 010 里&#xff08;推荐&#xff09; encDH~mqqvqxB^||zllJq~jkwpmvez{ key for i in enc:keychr…

程序员下班为什么不关电脑?难道在偷偷加班?!

不管是周围的程序员朋友还是网上的很多程序员朋友&#xff0c;在下班后都是习惯不关电脑的&#xff0c;关上显示器&#xff0c;拿上手机&#xff0c;快乐下班&#xff01; 那么&#xff0c;为什么程序员下班都不关电脑&#xff1f;难道他们在偷偷加班&#xff1f; 其实&#x…

elasticsearch源码分析-04集群状态发布

集群状态发布 cluster模块封装了在集群层面执行的任务&#xff0c;如集群健康、集群级元信息管理、分片分配给节点、节点管理等。集群任务执行之后可能会产生新的集群状态&#xff0c;如果产生新的集群状态主节点会将集群状态广播给其他节点。 集群状态封装在clusterState中&…

基于Qt实现的PDF阅读、编辑工具

记录一下实现pdf工具功能 语言&#xff1a;c、qt IDE&#xff1a;vs2017 环境&#xff1a;win10 一、功能演示&#xff1a; 二、功能介绍&#xff1a; 1.基于saribbon主体界面框架&#xff0c;该框架主要是为了实现类似word导航项 2.加载PDF放大缩小以及预览功能 3.pdf页面跳转…

Qt 网络编程 网络信息获取操作

学习目标&#xff1a;网络信息获取操作 前置环境 运行环境:qt creator 4.12 学习内容 一、Qt 网络编程基础 Qt 直接提供了网络编程模块,包括基于 TCP/IP 的客户端和服务器相关类,如 QTcpSocket/QTcpServer 和 QUdpSocket,以及实现 HTTP、FTP 等协议的高级类,如 QNetworkRe…

SPIN-Diffusion:自我博弈微调提升文本到图像扩散模型性能

扩散模型作为生成AI的关键实体&#xff0c;已经在多个领域展现出了卓越的能力。然而&#xff0c;现有的扩散模型&#xff0c;如Stable Diffusion和SDXL&#xff0c;通常在预训练阶段后需要进行微调以更好地符合人类偏好。最近&#xff0c;研究者们开始尝试使用强化学习&#xf…

矩阵键盘与密码锁

目录 1.矩阵键盘介绍​编辑 2.扫描的概念 3.代码演示&#xff08;读取矩阵键盘键码&#xff09; 4.矩阵键盘密码锁 1.矩阵键盘介绍 为了减少I/O口的占用&#xff0c;通常将按键排列成矩阵形式&#xff0c;采用逐行或逐列的 “扫描”&#xff0c;就可以读出任何位置按键的状态…

jenkins配置gitee源码地址连接不上

报错信息如下&#xff1a; 网上找了好多都没说具体原因&#xff0c;最后还是看jenkins控制台输出日志发现&#xff1a; ssh命令执行失败&#xff08;git环境有问题&#xff0c;可能插件没安装成功等其他问题&#xff09; 后面发现是jenkins配置git的地方git安装路径错了。新手…

帕金森病患者在选择运动疗法时应该注意哪些事项?

帕金森病患者在选择运动疗法时&#xff0c;应该遵循以下几点注意事项&#xff1a; 个性化运动处方&#xff1a;根据患者的病情、年龄、健康状况、以往运动能力等因素&#xff0c;制定个体化的运动处方。 避免运动负荷过大&#xff1a;运动时间不宜过长&#xff0c;注意控制心率…

机器学习 C++ 的opencv实现SVM图像二分类的测试 (三)【附源码】

机器学习 C 的opencv实现SVM图像二分类的测试 (三) 数据集合下载地址&#xff1a;https://download.csdn.net/download/hgaohr1021/89506900 根据上节得到的svm.xml&#xff0c;测试结果为&#xff1a; #include <stdio.h> #include <time.h> #include <o…

智慧生活新篇章,Vatee万腾平台领航前行

在21世纪的科技浪潮中&#xff0c;智慧生活已不再是一个遥远的梦想&#xff0c;而是正逐步成为我们日常生活的现实。从智能家居的温馨便捷&#xff0c;到智慧城市的高效运转&#xff0c;科技的每一次进步都在为我们的生活增添新的色彩。而在这场智慧生活的变革中&#xff0c;Va…

stm32定时器与pwm波

文章目录 4 TIM4.1 SysTick系统定时器4.2 TIM定时器中断与微秒级延时4.3 TIM使用PWM波4.3.1 PWM介绍4.3.2 无源蜂鸣器实现 4.4 TIM ,PWM常用函数 4 TIM 4.1 SysTick系统定时器 ​ Systick系统滴答&#xff0c;&#xff08;同时他有属于自己的中断&#xff0c;可以利用它来做看…

Star CCM+界面显示字体大小调整

前言 打开界面字体显示大小是默认的&#xff0c;软件内设置调整默认字体的大小是无法实现&#xff0c;需要在图标属性中进行设置&#xff0c;操作方法与中英文切换很类似&#xff0c;具体方法如下&#xff1a; 操作流程 1. 右击Star-CCM快捷⽅式&#xff0c;选择“属性”&…

【Mindspore进阶】-03.ShuffleNet实战

ShuffleNet图像分类 当前案例不支持在GPU设备上静态图模式运行&#xff0c;其他模式运行皆支持。 ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有…

lodash-es 基本使用

中文文档&#xff1a;https://www.lodashjs.com/ cloneDeep方法文档&#xff1a;https://www.lodashjs.com/docs/lodash.cloneDeep#_clonedeepvalue 参考掘金文章&#xff1a;https://juejin.cn/post/7354940462061715497 安装&#xff1a; pnpm install lodash-esnpm地址&a…

Ad-hoc命令和模块简介

华子目录 Ad-hoc命令和模块简介1.概念2.格式3.Ansible命令常用参数4.模块类型4.1 三种模块类型4.2Ansible核心模块和附加模块 示例1示例2 Ad-hoc命令和模块简介 1.概念 Ansible提供两种方式去完成任务&#xff0c;一是ad-hoc命令&#xff0c;一是写Ansible playbook(剧本)Ad-…

理解抽象工厂设计模式

目录 抽象工厂模式抽象工厂模式结构抽象工厂模式适合应用场景抽象工厂模式优缺点练手题目题目描述输入描述输出描述提示信息题解 抽象工厂模式 抽象工厂模式是一种创建型设计模式&#xff0c; 它能创建一系列相关的对象&#xff0c; 而无需指定其具体类。 抽象工厂模式结构 抽…

代码随想录Day69(图论Part05)

并查集 // 1.初始化 int fa[MAXN]; void init(int n) {for (int i1;i<n;i)fa[i]i; }// 2.查询 找到的祖先直接返回&#xff0c;未进行路径压缩 int.find(int i){if(fa[i] i)return i;// 递归出口&#xff0c;当到达了祖先位置&#xff0c;就返回祖先elsereturn find(fa[i])…

nginx的知识面试易考点

Nginx概念 Nginx 是一个高性能的 HTTP 和反向代理服务。其特点是占有内存少&#xff0c;并发能力强&#xff0c;事实上nginx的并发能力在同类型的网页服务器中表现较好。 Nginx 专为性能优化而开发&#xff0c;性能是其最重要的考量指标&#xff0c;实现上非常注重效率&#…

EasyExcel 单元格根据图片数量动态设置宽度

在使用 EasyExcel 导出 Excel 时&#xff0c;如果某个单元格是图片内容&#xff0c;且存在多张图片&#xff0c;此时就需要单元格根据图片数量动态设置宽度。 经过自己的研究和实验&#xff0c;导出效果如下&#xff1a; 具体代码如下&#xff1a; EasyExcel 版本 <depen…