【搜索】DFS迭代加深

news2024/12/29 9:34:25

目录

  • 迭代加深
    • 例题
      • 加成序列
        • 题意
        • 思路
        • 代码

迭代加深

搜索时可能会遇到这样一种情况:
在这里插入图片描述
明明答案就在第一层!但是因为DFS的缘故浪费很多时间
迭代加深就是用来解决这个问题的算法

定义一个 max_depth ,每次搜索时,超过这一层就全部剪掉、
(相当于我们划定一个区域,在这个区域内找解,如果找不到,再扩大区域)

?迭代加深和BFS有什么区别呢
BFS用队列存储,浪费空间,迭代加深本质是还是DFS,只存储本条路径,还是O(n)的算法

例题

加成序列

原题链接

满足如下条件的序列 X(序列中元素被标号为 1、2、3…m)被称为“加成序列”:

  1. X [ 1 ] = 1 X[1]=1 X[1]=1
  2. X [ m ] = n X[m]=n X[m]=n
  3. X [ 1 ] < X [ 2 ] < … < X [ m − 1 ] < X [ m ] X[1]<X[2]<…<X[m−1]<X[m] X[1]<X[2]<<X[m1]<X[m]
  4. 对于每个 k(2 ≤ k ≤ m)都存在两个整数 i 和 j (1 ≤ i , j ≤ k − 1,i 和 j 可相等),使得 X [ k ] = X [ i ] + X [ j ] X[k]=X[i]+X[j] X[k]=X[i]+X[j]

你的任务是:给定一个整数 n,找出符合上述条件的长度 m 最小的“加成序列”。

如果有多个满足要求的答案,只需要找出任意一个可行解。

输入格式

输入包含多组测试用例。

每组测试用例占据一行,包含一个整数 n。

当输入为单行的 0 时,表示输入结束。

输出格式

对于每个测试用例,输出一个满足需求的整数序列,数字之间用空格隔开。

每个输出占一行。

数据范围

1 ≤ n ≤ 100

输入样例

5
7
12
15
77
0

输出样例

1 2 4 5
1 2 4 6 7
1 2 4 8 12
1 2 4 5 10 15
1 2 4 8 9 17 34 68 77

题意

给出 n 构造一个序列,要求第一个数是1,最后一个数是n,严格递增,且后面的数一定要是前面两个数之和(两个数可以是同一个数),输出一个长度最小的序列

思路

序列的最小规模:1 2 4 8 16 32 64 128 此时就已经超过100了,说明正确答案的深度不会很深,适合用迭代加深来做
层数从1开始,依次考虑每一位选什么数字

优化:

  1. 优化搜索顺序:优先枚举较大的数,层数较少,更快的找到 n
  2. 排除等效冗余:举个栗子:1 2 3 4 现在枚举下一个数,不管选择1+4还是2+3结果都是5,就可以不用计算两次了(方法是开一个bool数组存储每个数是否被用过)

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 110;

int n;
int path[N];
bool st[N]; // 标记某数是否被用过

bool dfs(int u, int depth) // 分别是当前层数和最大层数
{
    if (u > depth) return false; // 当前层数>最大层数
    if (path[u - 1] == n) return true; // 最后一个数为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; // 大于最大值or小于前一个值or已被用过 都不满足条件

            st[s] = true; // 标记s已被用过
            path[u] = s; // 记录s
            if (dfs(u + 1, depth)) return true; // 下一位
            st[s] = false; // 恢复现场
        }

    return false;
}

int main()
{
    path[0] = 1;
    while (cin >> n, n)
    {
        memset(st, false, sizeof st);
        int depth = 1;
        while (!dfs(1, depth)) depth ++ ;
        for (int i = 0; i < depth; i ++ ) cout << path[i] << ' ';
        cout << '\n';
    }
}

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

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

相关文章

Spring事务(声明式事务)(Spring的事务,Spring隔离级别,事务传播机制)

目录 一、什么是事务&#xff0c;为什么要用事务 二、Spring声明式事务 &#x1f345; 1、Transactional的使用 &#x1f388; 事务回滚 &#x1f388;注意&#xff1a;异常被捕获&#xff0c;不会发生事务回滚 &#x1f345; 2、Transactional 作⽤范围 &#x1f345; …

硬盘的分类

目前常见的硬盘种类主要有以下2种&#xff1a; 机械硬盘&#xff08;HDD&#xff09; 机械硬盘&#xff08;HDD&#xff09;是一种利用旋转磁盘和读写头来存储和访问数据的存储设备。它由磁盘、读写头、电机和控制电路等组成&#xff0c;磁盘通常是一种铝合金或玻璃材质的圆盘&…

《HeadFirst设计模式(第二版)》第二章代码——观察者模式

代码文件目录结构&#xff1a; DisplayElement package Chapter2_ObserverPattern.interfaces;/*** Author 竹心* Date 2023/8/2**/public interface DisplayElement {public void display(); }Observer package Chapter2_ObserverPattern.interfaces;/*** Author 竹心* Date…

【win11+vs 2017+OpenCV4.5.5+Qt5.12配置】详细安装过程+小问题解决

0.版本选择 由于Qt5无法与最新的vs2022兼容&#xff0c;扩展工具中一直显示不可用&#xff0c;所以将vs降级成vs2017。 在安装Qt的过程中&#xff0c;会选择安装Qt套件&#xff0c;其中就的MCVS 2017&#xff0c;说明vs2017是与qt兼容的。 当然也可以用qt creator这一原生IDE。…

PROFINet转Modbus协议转换网关Profinet数据通讯模块

产品概述 你是否曾经遇到过不同网络协议之间的沟通问题&#xff1f;捷米特JM-RTU-PN为你解决这个难题&#xff01; 捷米特JM-RTU-PN是一款数据通讯模块&#xff0c;能够实现PROFINet网络与Modbus网络之间的数据传输。它可以将RS485网络连接到PROFINet网络&#xff0c;并支持不…

《剑指offer》刷题(1)链表篇

class ListNode: def __init__(self, x): self.val x self.next None class Solution: def printListFromTailToHead(self , listNode: ListNode) -> List[int]: #用栈记录遍历的结果&#xff0c;然后返回出栈结果 if listNode is None: return [] stack [] p listNode…

8.2Thread类的常见属性

1. 2.前台线程和后台线程 前台线程:影响进程结束(如果前台线程没有执行完,进程不结束). 后台线程(守护线程):不影响线程结束. 创建线程默认是前台线程. 修改成后台线程:thread.setDaetrue);

33.利用abs 解决绝对值问题(matlab程序 )

1.简述 abs函数的功能是绝对值和复数的模 语法 Y abs(X) 说明 Y abs(X) 返回数组 X 中每个元素的绝对值。如果 X 是复数&#xff0c;则 abs(X) 返回复数的模。 示例 标量的绝对值 y abs(-5) y 5 向量的绝对值 创建实值的数值向量。 x [1.3 -3.56 8.23 -5 -0.01…

ARP断网攻击及防御

ARP断网攻击及防御 攻击防御 攻击 PC1的IP地址 10.9.136.222 PC2的IP地址 10.9.136.55在局域网里通信 需要有IP地址和MAC地址 两台电脑PC1和PC2要想相互通信&#xff0c;PC1在连接PC2的时候&#xff0c;PC1会先查看自己的ARP缓存表&#xff08;命令&#xff1a;arp -a &#xf…

利用鸿鹄可观测性监控Istio Ingress网关

一、需求描述 在上一篇《利用Vector和鸿鹄搭建微服务应用的可观测性平台》中&#xff0c;阐述了微服务的基本概念、优点及如何利用鸿鹄来处理分布式应用的日志。本文将进一步讨论微服务架构面临的问题、服务网格及鸿鹄处理Istio Gateway的独特优势。 1.1 微服务架构面临的挑战 …

学习委员之作业管理系统—前端部分

拯救学习委员之作业管理系统—前端部分 项目背景 学习委员收集作业的过程&#xff0c;繁琐且曲折&#xff0c;作者充分理解并体谅为大家服务的苦逼学习委员&#xff0c;以此为出发点和灵感&#xff0c;设计并开发了此套作业管理系统&#xff0c;希望能帮助各位提高效率&#…

语义检索系统【三】:基于Milvus 搭建召回系统抽取向量进行检索,加速索引

搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术细节以及项目实战(含码源) 专栏详细介绍:搜索推荐系统专栏简介:搜索推荐全流程讲解(召回粗排精排重排混排)、系统架构、常见问题、算法项目实战总结、技术…

[openCV]基于拟合中线的智能车巡线方案V4

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…

Linux(四)--包软件管理器与Linux上软件的下载示例

一.包软件管理器【yum和apt】 1.先来学习使用yum命令。yum&#xff1a;RPM包软件管理器&#xff0c;用于自动化安装配置Linux软件&#xff0c;并可以自动解决依赖问题。通过yum命令我们可以轻松实现软件的下载&#xff0c;查找&#xff0c;卸载与更新等管理软件的操作。 最常用…

线程池-手写线程池Linux C简单版本(生产者-消费者模型)

目录 简介手写线程池线程池结构体分析task_ttask_queue_tthread_pool_t 线程池函数分析thread_pool_createthread_pool_postthread_workerthread_pool_destroywait_all_donethread_pool_free 主函数调用 运行结果 简介 本线程池采用C语言实现 线程池的场景&#xff1a; 当某些…

Delphi 开发的QR二维码生成工具,开箱即用

目录 一、基本功能&#xff1a; 二、使用说明&#xff1a; 三、操作演示gif 四、下载链接 在日常的开发中&#xff0c;经常需要将一个链接生成为二维码图片&#xff0c;特别是在进行支付开发的时候&#xff0c;因为我们支付后台获取了支付链接&#xff0c;需要变成二维码扫…

设计模式行为型——解释器模式

目录 什么是解释器模式 解释器模式的实现 解释器模式角色 解释器模式类图 解释器模式举例 解释器模式代码实现 解释器模式的特点 优点 缺点 使用场景 注意事项 实际应用 什么是解释器模式 解释器模式&#xff08;Interpreter Pattern&#xff09;属于行为型模式&…

SOLIDWORKS中的弹簧设计指南

SOLIDWORKS是一款广泛使用的三维计算机辅助设计软件&#xff0c;可以用于设计各种机械零件和组件&#xff0c;包括弹簧。在SOLIDWORKS中设计弹簧需要注意一些关键点&#xff0c;本文将为您介绍SOLIDWORKS中的弹簧设计指南。 1. 弹簧类型 按受力性质&#xff0c;弹簧类型包括压…

小程序云开发快速入门(1/4)

前言 从上次完成了码仔备忘录本地版本后&#xff0c;码仔就养成了每天记录备忘录的好习惯&#xff0c;每周早上会记录下自己要做的任务&#xff0c;然后晚上在复盘一下今天的计划是否完成。 有一天&#xff0c;码仔看到它最喜欢的码妞在一旁愁眉苦脸。 码仔&#xff1a;“怎么…

5个设计师必备的绘画工具,不看错亿

在设计工作中&#xff0c;绘画工具是设计师经常会用到的设计工具&#xff0c;今天本文将与大家分享5个好用的绘画工具&#xff0c;一起来看看吧&#xff01; 1、即时灵感 即时灵感是一款非常受欢迎的绘画工具&#xff0c;它为设计师提供了自由的绘画方式&#xff0c;也提供了…