《算法竞赛进阶指南》0x24迭代加深

2024-08-26 11:28

本文主要是介绍《算法竞赛进阶指南》0x24迭代加深,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

迭代加深

深度优先搜索每次选定发一个分支,不断深入,直到达到递归边界才回溯。但是如果每个节点的分支非常多,并且问题的答案在某一个较浅的节点,如果一开始就选错了分支,就可能在不包含答案的子树上浪费时间。
此时,我们可以从小到大限制搜索的深度,如果在当前深度下搜不到答案,就把深度限制增加,重新进行一遍搜索。这就是迭代加深的思想。
总而言之,当搜索树地规模随着层次的深入增长很快,并且我们能保证答案在较浅层地节点时,就可以使用迭代加深地深度优先搜索算法来解决问题。

例题

acwing170.加成序列

搜索框架:依次搜索序列的每个位置k,枚举i,j作为分支,把X[i]和X[j]的和填到X[k],然后递归填写下一个位置。
加入以下剪枝
1.优化搜索顺序
为了让序列中的数金肯逼近n,在枚举i,j时从大到小枚举。
2.排除等效冗余
对于不同的i,j,X[i]+X[j]可能是相等的,我们可以对他进行排重,避免重复搜索某一个和。
经过分析,m的值不会太大,不超过10,枚举两个数的和分支会很多,因此可以使用迭代加深。

#include<iostream>
using namespace std;
int arr[110];
int n;
bool dfs(int now,int dep)
{if(now==dep)return arr[now]==n;bool st[110]={0};for(int i=now;i>=1;i--)for(int j=i;j>=1;j--){int s=arr[i]+arr[j];if(s>n||st[s]||s<=arr[now])continue;st[s]=true;arr[now+1]=s;if(dfs(now+1,dep))return true;}return false;
}
int main()
{arr[1]=1;while(cin>>n,n){int dep=1;while(!dfs(1,dep))dep++;for(int i=1;i<=dep;i++)cout<<arr[i]<<" ";cout<<endl;}return 0;
}

双向搜索

在一些题目中,问题不但具有初态,还具有明确的终态,并且从初态与终态进行搜索都能覆盖整个状态空间。在这种情况下可以使用双向搜索——从初态和终态各出发搜索一半状态,产生两棵深度减半的搜索树,在中间交会,组合成最终的答案。

例题

acwing171.送礼物
首先这道题目肯定是要搜索的,因为如果说用DP做的话,那么这个W值太大了,但是如果说只是普通搜索的话,那么O(2^N)的复杂度足以超时,而且这道题目重点就是,我们已经知道了初态而且还知道了终态,既然如此的话,我们可以选择双向搜索.
根据双向搜索的性质,我们大致可以确定当前搜索的范围,首先从前一半个物品中,挑选任意多个物品,然后将这些物品的权值总和加入到数组S中,然后我们就会发现在这个S数组中有很多很多的重复的数值,我们可使用unique进行删除.然后我们现在前半部分搜索完后,开始搜索后半部分,至于后半部分搜索,其实和前半部分一模一样,只是我们需要二分找到当前可以填写的最大值.
时间复杂度 O ( 2 N / 2 l o g 2 N / 2 ) = O ( N ∗ 2 N / 2 ) O(2^{N/2}log2^{N/2})=O(N*2^{N/2}) O(2N/2log2N/2)=O(N2N/2)

#include<iostream>
#include<algorithm>
using namespace std;
#define M 1<<25
#define N 50
int w,n,k,cnt=1;
int g[N],sum[M];
int ans=0;
void dfs1(int now,int weight)
{if(now>k){sum[cnt++]=weight;return ;}dfs1(now+1,weight);if((long long)weight+g[now]<=w)dfs1(now+1,weight+g[now]);return ;
}
void dfs2(int now,int weight)
{if(now>n){int l=0,r=cnt;while(l<r){int mid=(l+r+1)>>1;if(sum[mid]<=w-weight)l=mid;else r=mid-1;}ans=max(ans,sum[l]+weight);return ;}dfs2(now+1,weight);if((long long)weight+g[now]<=w)dfs2(now+1,weight+g[now]);return ;
}
int main()
{cin>>w>>n;k=n/2+2;for(int i=1;i<=n;i++)cin>>g[i];sort(g+1,g+1+n);reverse(g+1,g+1+n);dfs1(1,0);sort(sum+1,sum+cnt+1);cnt=unique(sum+1,sum+cnt+1)-sum-1;dfs2(k+1,0);cout<<ans;return 0;
}

这篇关于《算法竞赛进阶指南》0x24迭代加深的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1108429

相关文章

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Python使用qrcode库实现生成二维码的操作指南

《Python使用qrcode库实现生成二维码的操作指南》二维码是一种广泛使用的二维条码,因其高效的数据存储能力和易于扫描的特点,广泛应用于支付、身份验证、营销推广等领域,Pythonqrcode库是... 目录一、安装 python qrcode 库二、基本使用方法1. 生成简单二维码2. 生成带 Log

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

macOS怎么轻松更换App图标? Mac电脑图标更换指南

《macOS怎么轻松更换App图标?Mac电脑图标更换指南》想要给你的Mac电脑按照自己的喜好来更换App图标?其实非常简单,只需要两步就能搞定,下面我来详细讲解一下... 虽然 MACOS 的个性化定制选项已经「缩水」,不如早期版本那么丰富,www.chinasem.cn但我们仍然可以按照自己的喜好来更换

Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南

《Python使用Pandas库将Excel数据叠加生成新DataFrame的操作指南》在日常数据处理工作中,我们经常需要将不同Excel文档中的数据整合到一个新的DataFrame中,以便进行进一步... 目录一、准备工作二、读取Excel文件三、数据叠加四、处理重复数据(可选)五、保存新DataFram

使用JavaScript将PDF页面中的标注扁平化的操作指南

《使用JavaScript将PDF页面中的标注扁平化的操作指南》扁平化(flatten)操作可以将标注作为矢量图形包含在PDF页面的内容中,使其不可编辑,DynamsoftDocumentViewer... 目录使用Dynamsoft Document Viewer打开一个PDF文件并启用标注添加功能扁平化

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

如何安装 Ubuntu 24.04 LTS 桌面版或服务器? Ubuntu安装指南

《如何安装Ubuntu24.04LTS桌面版或服务器?Ubuntu安装指南》对于我们程序员来说,有一个好用的操作系统、好的编程环境也是很重要,如何安装Ubuntu24.04LTS桌面... Ubuntu 24.04 LTS,代号 Noble NumBAT,于 2024 年 4 月 25 日正式发布,引入了众

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin