meet-in-the-middle 基础算法(优化dfs)
$meet-in-the-middle$(又称折半搜索、双向搜索)对于$n<=40$的搜索类型题目,一般都可以采用该算法进行优化,很稳很暴力。
$meet-in-the-middle$算法的主要思想是将搜索区域化为两个集合,分别由搜索树的两端向中间扩展,直到搜索树产生交集,此时即可得到我们的合法情况。
通常适用于求经过$n$步变化,从A集合变到B集合需要的方案数问题。
对于普通dfs来说,其一大弊端是随着搜索层数的不断增加,搜索的复杂度也会极速增长,
而$meet-in-the-middle$算法能够将搜索层数降至原来的一半,对整体效率而言无疑是不小的提升。
如图所示:


可以明显看出$meet-in-the-middle$对于dfs优化之显著。
那么考虑$meet-in-the-middle$的算法流程:
1、从状态$L$出发,经过$x$步状态扩展,记录到达状态$i$的步数,通常这里会与状压、二分等内容结合。
2、从状态$R$出发,经过$y$步状态扩展,若同样到达状态$i$并且步数不为0,则累加答案。
通常我们需要保证$x+y=n$,也就是需要满足状态总数不变,只是深度减少,一般情况下取$x=y=(n>>1)$最优
但具体情况应视题而定,可能搜索深度不均匀时,效率反而会更高。
下面来看一道例题:
[BZOJ 2679] Balanced Cow Subsets
简要题意:有多少个非空子集,能划分成和相等的两份。$(n<=20)$
分析:显然的$meet-in-the-middle$定义,考虑如何转化
将题设转化成方程的形式$a1x1+a2x2+a3x3+...+anxn=0$,其中$x=0,1,-1$(表示不选,选入集合$l$,选入集合$r$),那么移项可得一种两侧各有一种集合的形式,根据题目要求,我们需要求出可以构建出该方程的集合方案数,可以采用状压的思想,记录所选取的数的和以及选取集合的状态即可。
#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define re register
using namespace std;
int n,a[],cntl,cntr,ans=-;
bool vis[<<];
inline int read(){
re int a=,b=; re char ch=getchar();
while(ch<''||ch>'')
b=(ch=='-')?-:,ch=getchar();
while(ch>=''&&ch<='')
a=(a<<)+(a<<)+(ch^),ch=getchar();
return a*b;
}
struct node{
int sta,val; node(){}
node(int x,int y){sta=x,val=y;}
bool operator < (const node &b) const {
return val<b.val;
}
bool operator > (const node &b) const {
return val>b.val;
}
}l[<<],r[<<];
inline void dfs1(re int x,re int tot,re int sta){
if(x>(n>>)){
l[++cntl]=node(sta,tot);
return ;
}
dfs1(x+,tot,sta);
dfs1(x+,tot+a[x],sta|(<<(x-)));
dfs1(x+,tot-a[x],sta|(<<(x-)));
}
inline void dfs2(re int x,re int tot,re int sta){
if(x>n){
r[++cntr]=node(sta,tot);
return ;
}
dfs2(x+,tot,sta);
dfs2(x+,tot+a[x],sta|(<<(x-)));
dfs2(x+,tot-a[x],sta|(<<(x-)));
}
signed main(){
n=read();
for(re int i=;i<=n;++i) a[i]=read();
dfs1(,,); dfs2((n>>)+,,);
sort(l+,l+cntl+,less<node>());
sort(r+,r+cntr+,greater<node>());
for(re int i=,j=,pos;i<=cntl&&j<=cntr;++i){
while(j<=cntr&&l[i].val+r[j].val>) ++j;
for(pos=j;l[i].val==-r[pos].val;++pos){
re int sta=(l[i].sta|r[pos].sta);
if(!vis[sta]) vis[sta]=,++ans;
}
}
printf("%d\n",ans);
}
Code
同种类的题目还有许多,例如 [POJ 1186] 方程的解数, [BZOJ 4800] 冰球世界锦标赛 等。
综上可见$meet-in-the-middle$算法的应用之广。
至此,通过分析转化搜索模型,达到了降低搜索复杂度,优化程序效率的目的。
meet-in-the-middle 基础算法(优化dfs)的更多相关文章
- 【BZOJ4800】[Ceoi2015]Ice Hockey World Championship Meet in the Middle
[BZOJ4800][Ceoi2015]Ice Hockey World Championship Description 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. Input 第一 ...
- Meet in the middle算法总结 (附模板及SPOJ ABCDEF、BZOJ4800、POJ 1186、BZOJ 2679 题解)
目录 Meet in the Middle 总结 1.算法模型 1.1 Meet in the Middle算法的适用范围 1.2Meet in the Middle的基本思想 1.3Meet in ...
- 0基础算法基础学算法 第八弹 递归进阶,dfs第一讲
最近很有一段时间没有更新了,主要是因为我要去参加一个重要的考试----小升初!作为一个武汉的兢兢业业的小学生当然要去试一试我们那里最好的几个学校的考试了,总之因为很多的原因放了好久的鸽子,不过从今天开 ...
- 折半搜索(meet in the middle)
折半搜索(meet in the middle) 我们经常会遇见一些暴力枚举的题目,但是由于时间复杂度太过庞大不得不放弃. 由于子树分支是指数性增长,所以我们考虑将其折半优化; 前言 这个 ...
- Meet in the middle
搜索是\(OI\)中一个十分基础也十分重要的部分,近年来搜索题目越来越少,逐渐淡出人们的视野.但一些对搜索的优化,例如\(A\)*,迭代加深依旧会不时出现.本文讨论另一种搜索--折半搜索\((meet ...
- 浅谈Meet in the middle——MITM
目测观看人数 \(0+0+0=0\) \(\mathrm{Meet\;in\;the\;middle}\)(简称 \(\rm MITM\)),顾名思义就是在中间相遇. 可以理解为就是起点跑搜索树基本一 ...
- ACM基础算法入门及题目列表
对于刚进入大学的计算机类同学来说,算法与程序设计竞赛算是不错的选择,因为我们每天都在解决问题,锻炼着解决问题的能力. 这里以TZOJ题目为例,如果为其他平台题目我会标注出来,同时我的主页也欢迎大家去访 ...
- DAY 4 基础算法
基础算法 本来今天是要讲枚举暴力还有什么的,没想到老师就说句那种题目就猪国杀,还说只是难打,不是难.... STL(一)set 感觉今天讲了好多,set,单调栈,单调队列,单调栈和单调队列保证了序列的 ...
- 【算法】342- JavaScript常用基础算法
一个算法只是一个把确定的数据结构的输入转化为一个确定的数据结构的输出的function.算法内在的逻辑决定了如何转换. 基础算法 一.排序 1.冒泡排序 //冒泡排序function bubbleSo ...
- SQL Server 聚合函数算法优化技巧
Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值 ...
随机推荐
- 基本包装类型Boolean、Number、String特性及常用方法
基本包装类型:Boolean.Number.String 一.String 字符串常用方法 1.indexOf() lastIndexOf() 返回相应字符的索引号 2.slice(index1, ...
- 180608发现的一个有趣的Douyin-Bot项目
今日发现的github 项目 Douyin-Bot 抖音机器人发现漂亮小姐姐 :sweat_smile: 在开发者模式下,找到指针位置,开启之后,当点击屏幕时,可以获取点击屏幕处的xy坐标了 我使用的 ...
- 1.前端数据可视化插件:Highcharts、Echarts和D3(区别)
前端数据可视化插件有很多,但我用过的只有Highcharts(https://www.hcharts.cn/).Echarts(http://echarts.baidu.com/)和D3(https: ...
- maven 工程搭建
使用Maven建立一个Quite start 项目 2.命名卫 bhz-parent 3.groupid 为: bhz 4.artifactId 为: bhz-parent package:为空不填 ...
- react antd样式按需加载配置以及与css modules模块化的冲突问题
通过create-react-app脚手架生成一个项目 然后运行npm run eject 把webpack的一些配置从react-scripts模块弹射出来, 方便自己手工增减,暴露出来的配置文件在 ...
- OpenCASCADE 平面与球面求交
OpenCASCADE 平面与球面求交 eryar@163.com OpenCASCADE提供了类IntAna_QuadQuadGeo用来计算两个二次曲面quadric(球面.圆柱面.圆锥面及平面,平 ...
- <每日一题>题目7:简单的学生管理系统V1.0
''' # 学生管理系统v1.0 # 添加学生的信息 # 删除学生的信息 # 修改学生的信息 # 查看学生的信息 #遍历学生的信息 #退出系统 ''' import json #1 显示操作功能 de ...
- 04-4-typeof
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- NoSQL与关系数据库的比较
- AlexNet结构图详解