【Acwing170】加成序列(dfs+迭代加深+剪枝)题解和一点感想

本思路来自acwing算法提高课

题目描述

看本文需要准备的知识

1.dfs算法基本思想

2.对剪枝这个词有个简单的认识

迭代加深思想和此题分析

首先,什么是迭代加深呢?当一个问题的解有很大概率出现在递归树很浅的层,但是这个问题的解本身存在着很深的层,当这个很浅的层的对应分支在搜索顺序比较靠后的位置时,我们就会先搜索前几个很深的层,导致浪费大量时间,迭代加深就是为了解决这个问题(如下图所示)而存在的

迭代加深具体思想非常简单,设置一个max_depth,每次搜索超过这个值直接return,如果搜完没搜到就逐步扩大max_depth

比如上面那个图,刚开始max_depth==1,对于左边那一堆,往下搜一个没搜到直接return,轮到第二个分支,往下搜一个,直接就找到答案了!如果答案在第二个分支的第二层,就会从最左边开始先往下搜两个没找到,就开始搜第二个分支往下看两个,就又找到了。

有人可能会问,这样反复搜之前搜过的部分,不会导致效率低吗?

举一个满二叉树的例子吧!

假设答案在第8层,在max_depth从1到8的过程中,会先搜索:

2^1+2^2+......+2^7<2^8

所以相对第8层而言,这个重复搜索不值一提

而对于这个题目,举一个例子:n=127时,可以是1,2,4,8,16,32,64,仅仅第7层就可以搜到,而如果按照正常搜索顺序去搜,举一个极端例子,可以这样:

1,2,填第三个时,可以填1+2=3,

1,2,3填第四个时,可以填1+3=4,

依次类推,甚至可以搜一百多层!!!相对于第7层而言,这做出了极大的优化!

最后我们可以发现,这有一种bfs的味道,感觉就像是迭代加深把dfs的优势和bfs做了融合一样

剪枝

本题可以做几个剪枝

1.优化搜索顺序,每层的搜索大的开始,这样分支数会减少

2.可行性剪枝,当某层上可能填入的数小于等于当前确定序列的最后一个数,或者大于n,那么就不选这个数

3.去掉冗余,比如1,2,3,4,该搜第五个数时,2+3=1+4所以如果1+4已经搜过就不用弄2+3了,故设立st数组,标记已经搜过的,下次再见时直接continue本次循环

本题感想

这道题目,对于st数组到底是每层初始化一次还是每棵递归树整体初始化一次这个问题,我思考了很长时间,虽然知道结果是前者,但始终找不到其中的原因,现在我想通了,找这个原因其实是没有必要的,而且是很难的,因为dfs层与层之间的调用会导致各种数组变量结果变化,我们寻找这种具体变化和影响是极其艰难的,所以我们需要做的事弄清st数组应该作用于什么地方就行了,本题st数组的目的就是仅仅为了排除二重循环的X[i]+X[j]相同的冗余问题,既然仅仅作用于二重循环,我们也仅仅需要在二重循环前面开一个st数组即可

代码

#include<iostream>
#include<cstring>
using namespace std;
const int N=110;
int path[N];
int n;
bool dfs(int u,int k)
{if(u==k)return path[u-1]==n;bool st[N];memset(st,0,sizeof st);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;path[u]=s;st[s]=true;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;
}

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

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

相关文章

音视频开发:音频编码原理+采集+编码实战

原理&#xff1a; 消除冗余信息&#xff0c;压缩量最大&#xff0c;也叫有损压缩 剔除人耳听觉范围外的音频信号20Hz以下和20000Hz以上&#xff1b;去除被掩蔽的音频信号&#xff0c;信号的遮蔽可以分为频域遮蔽和时域遮蔽&#xff1b;频域遮蔽效应 屏蔽70分贝以下&#xff0…

汽车标定技术(一):XCP概述

目录 1.汽车标定概述 2.XCP协议由来及版本介绍 3.XCP技术通览 3.1 XCP上下机通信模型 3.2 XCP指令集 3.2.1 XCP帧结构定义 3.2.2 标准指令集 3.2.3 标定指令集 3.2.4 页切换指令集 3.2.5 数据采集指令集 3.2.6 刷写指令集 3.3 ECU描述文件(A2L)概述 3.3.1 标定上位…

C++中何时及如何使用析构函数

C中何时及如何使用析构函数 析构函数不返回任何值&#xff0c;没有返回类型&#xff0c;也没有函数参数。由于没 有函数参数&#xff0c;因此它不能被重载。换言之&#xff0c;一个类可以有多个构造函数&#xff0c;但是只能有一个析构函数。 何时调用析构函数&#xff1a; &…

有方N58 HTTP POST 请求连接 TDengine

串口调试软件&#xff1a;格西调试精灵 第一步先注册网络获取IP地址 建立PPP连接 ATXIIC1\r PPP链路建立成功&#xff0c;查询IP地址 ATXIIC?\r 设置网络APN ATCREG?\r 运行结果&#xff0c;红线处是获…

js:可选链运算符(?.)和空值合并运算符(??)

文档&#xff1a; 可选链运算符&#xff08;?.&#xff09;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining空值合并运算符&#xff08;??&#xff09;https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Referenc…

【算法与数据结构】--算法和数据结构的进阶主题--并行算法和分布式数据结构

一、并行算法 1.1 并行计算概述 并行计算是一种计算方法&#xff0c;旨在通过同时执行多个计算任务来提高计算性能和效率。与传统的串行计算不同&#xff0c;其中每个任务按顺序执行&#xff0c;并行计算允许多个任务同时执行。这种并行性通常通过将计算任务分解为较小的子任…

算法:Java构建二叉树并迭代实现二叉树的前序、中序、后序遍历

先自定义一下二叉树的类&#xff1a; // Definition for a binary tree node. public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left…

MongoDB安装及开发系例全教程

一、系列文章目录 一、MongoDB安装教程—官方原版 二、MongoDB 使用教程(配置、管理、监控)_linux mongodb 监控 三、MongoDB 基于角色的访问控制 四、MongoDB用户管理 五、MongoDB基础知识详解 六、MongoDB—Indexs 七、MongoDB事务详解 八、MongoDB分片教程 九、Mo…

ATE新能源汽车充电桩自动负载测试系统

随着新能源汽车的普及&#xff0c;充电桩的需求也在不断增加&#xff0c;为了确保充电桩的性能和安全性&#xff0c;对其进行负载测试是非常重要的。ATE新能源汽车充电桩自动负载测试系统是一种专门用于检测充电桩性能的设备&#xff0c;它可以模拟各种实际使用场景&#xff0c…

6、QtCharts 悬浮曲线效果

文章目录 效果dialog.hdialog.cpp悬浮槽函数 效果 dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QDialog> #include <QtCharts> #include <QLineSeries> #include <QGraphicsScene> #include <QTimer> #include <QSplineSeries>…

《实战:如何搭建一个完整的 Vue2.0 项目》- 7、Vue2.x 项目 webpack 4 升级 5(半自动升级)

1.自动升级 先全局安装升级插件 npm i npm-check npm-check-updates -g检查依赖 npm-check更新检查后的依赖并展示版本号&#xff0c;此时 package.json还没有更新 npm-check-updates升级 package.json&#xff0c;下图显示更新版本&#xff0c;此时 package.json文件已变更…

【JavaScript】变量提升

变量提升&#xff08;Hoisting&#xff09;被认为是&#xff0c;Javascript 中执行上下文&#xff08;特别是创建和执行阶段&#xff09;工作方式的一种认识。 提升&#xff08;Hoisting&#xff09;这个词。不过&#xff0c;需要注意的是&#xff0c;开始时&#xff0c;这个概…

FFmpeg——使用Canvas录制视频尚存问题的解决方案

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

编译正点原子LINUXB报错make: arm-linux-gnueabihf-gcc:命令未找到

编译正点原子LINUX报错make: arm-linux-gnueabihf-gcc&#xff1a;命令未找到 1.报错内容2.解决办法3./bin/sh: 1: lzop: not found4.编译成功 1.报错内容 make: arm-linux-gnueabihf-gcc&#xff1a;命令未找到CHK include/config/kernel.releaseCHK include/generat…

lamba stream处理集合

lamba stream处理集合 带拼接多字段分组List< Object> 转 Map<String,List< Object>> Map<String, List<ProfitAndLossMapping>> collect plMappingList.stream() .collect(Collectors.groupingBy(m -> m.getLosType() ":" m.…

Linux 上的轻量级浏览器

导读大多数 Linux 桌面环境中包含的基本图像查看器可能不足以满足你的需要。如果你想要一些更多的功能&#xff0c;但仍然希望它是轻量级的&#xff0c;那么看看这四个 Linux 桌面中的图像查看器&#xff0c;如果还不能满足你的需要&#xff0c;还有额外的选择。 当你需要的不…

本地部署Jellyfin影音服务器并实现远程访问影音库

文章目录 1. 前言2. Jellyfin服务网站搭建2.1. Jellyfin下载和安装2.2. Jellyfin网页测试 3.本地网页发布3.1 cpolar的安装和注册3.2 Cpolar云端设置3.3 Cpolar本地设置 4.公网访问测试5. 结语 1. 前言 随着移动智能设备的普及&#xff0c;各种各样的使用需求也被开发出来&…

表格冻结第二行

在网上找了一圈也没找到说明白的。 像这样的表格下面会有很多行&#xff0c;往下翻的时候会忘记第二行显示的什么内容。 需求&#xff1a;将第二行进行冻结 实现&#xff1a; 1&#xff0c;选中第一和第二行&#xff0c;下拉&#xff0c;点击冻结 2&#xff0c;会显示冻结至…

会声会影2024出来了吗?会声会影2024这款视频剪辑软件怎么样?

众所周知&#xff0c;每每有新兴行业逐渐崛起壮大的时候&#xff0c;随机而来的就是这个行业创造出的衍生行业&#xff0c;比如说现在的短视频平台或者是视频剪辑行业&#xff0c;都是很明显例子&#xff0c;今天我们就针对剪辑软件来和大家聊一聊&#xff0c;会声会影2024这款…