首页 > 其他分享 >Meet in the middle

Meet in the middle

时间:2024-10-14 11:36:13浏览次数:1  
标签:le int ll middle mp Meet now

Meet in the middle 双端搜索

不是怎么这个人现在才会双端搜索


Meet in the middle,顾名思义,就是从两端进行搜索,然后把两端的答案合并得到最终答案。

如果原本的搜索时间复杂度为 \(O(a^b)\),那么 Meet in the middle 可以将搜索的时间复杂度优化到 \(O(wa^{\frac{b}{2}})\),其中 \(w\) 为一个常数。

思路很简单,直接实战。上链接。

P5691 [NOI2001] 方程的解数

给定 \(n\),\(k_1,k_2,...,k_n\),\(p_1,p_2,...,p_n\) 求

\[\sum \limits_{i=1}^n k_ix_i^{p_i}=0 \]

的正整数解个数,其中 \(x \in [1,m] \ (i \in [1,n])\)。

\(1 \le n \le 6\),\(1 \le m \le 150\)。

看到这题一眼爆搜,但很明显时间复杂度是 \(O(m^n)\) 的过不了。

考虑 Meet in the middle,处理前半部分和后半部分再合并。

How 合并?

由于最终的和为 \(0\),我们只需在处理后半部分时找前半部分选取的和为后半部分选取的和相反数的方案即可。

于是开一个 map 记录前半部分选取对应的和的方案数,后半部分搜索完后从 map 里查找并更新答案即可。

时间复杂度 \(O(wm^{\frac{n}{2}})\),其中 \(w\) 是 map 的常数。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=10;
map<ll,int> mp;
int n,m;
ll k[N],p[N],ans;
ll qpow(ll a,ll b){//快速幂,搜索时累加和用的
	ll res=1,x=a;
	while(b){
		if(b&1)res*=x;
		x*=x;
		b>>=1;
	}
	return res;
}
void dfs1(int x,ll sum){//前半
	if(x>(n>>1)){
		mp[sum]++;//记录
		return;
	}
	for(int i=1;i<=m;i++)//枚举下一步的选值
		dfs1(x+1,sum+k[x]*qpow(i,p[x]));
}
void dfs2(int x,ll sum){//后半
	if(x>n){
		ans+=mp[-sum];//找相反数的方案数
		return;
	}
	for(int i=1;i<=m;i++)
		dfs2(x+1,sum+k[x]*qpow(i,p[x]));
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>k[i]>>p[i];
	dfs1(1,0);
	dfs2((n>>1)+1,0);
	cout<<ans;
	return 0;
} 

做完这道再来看下一道:

P2962 [USACO09NOV] Lights G

有一张 \(n\) 个点 \(m\) 条边的无向图,每次操作一个点使其权值异或 \(1\),与其连边的节点也会异或 \(1\),求最小的操作次数。

\(1 \le n \le 35\),\(1 \le m \le 595\)。没有重边和自环。

dfs 需要记录三个信息:当前所在的节点,状态和次数。

Meet in the middle,由于直接枚举相邻节点并统计状态相当不方便且肯定超时,且 \(n\) 的范围很小,于是我们可以状态压缩每一个节点会影响的节点(包括自身)与 dfs 中节点的状态。

考虑前半部分与后半部分能合并的条件:当且仅当所有的点权值都为 \(1\),即当 front^now==(1<<n)-1 时方案才合法。

于是还是用 map 来维护,但这一次统计的是到达当前状态时至少需要几步。后半部分合并时,根据异或的性质有 front=now^((1<<n)-1) ,即如果 map 统计了 now^((1<<n)-1) 那么就可以用于更新最优解。

只加了 inline 用于卡常但没吸氧,跑得飞快。

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=40,M=600;
map<ll,int> mp;
int n,m;ll s[N];
//s[i] 按下i对其他点产生的影响 
int ans=0x3f3f3f3f;
inline void dfs1(int x,ll now,int t){
	if(x>(n>>1)){//统计步数
		if(!mp.count(now))mp[now]=t;
		else mp[now]=min(mp[now],t);
		return; 
	}
	dfs1(x+1,now,t);
	dfs1(x+1,now^s[x],t+1);
}
inline void dfs2(int x,ll now,int t){
	if(x>n){
		if(mp.count(((1ll<<n)-1)^now))//如果这种状态是可行的
			ans=min(ans,mp[((1ll<<n)-1)^now]+t);//更新答案
		return;
	}
	dfs2(x+1,now,t);
	dfs2(x+1,now^s[x],t+1);
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		s[i]|=1<<i-1;//状压
	for(int i=1;i<=m;i++){
		int u,v;
		cin>>u>>v;
		s[u]|=1ll<<v-1;
		s[v]|=1ll<<u-1;
	}
	dfs1(1,0,0);
	dfs2((n>>1)+1,0,0);
	cout<<ans;
	return 0;
}

现在你已经学会了 Meet in the middle,快去做题看看实力吧。

标签:le,int,ll,middle,mp,Meet,now
From: https://www.cnblogs.com/z-Sqrt-xf/p/-/Meet-in-the-middle

相关文章

  • 【第4期】搜索客 Meetup | INIFNI Pizza 网站 SVG 动画这么炫,我教你啊!
    本次Meetup活动由搜索客社区、极限科技(INFINILabs)联合举办,活动主题将从设计师的角度出发,探讨如何在零编程基础下,借助ChatGPT和SVG,搞定INIFNIPizza首页动效,从设计到实现,探索AI的更多玩法。欢迎大家预约报名参加和交流。活动主题:INIFNIPizza网站SVG动画这么炫,我教......
  • ACL(Annual Meeting of the Association for Computational Linguistics)近十年研究热
    ACL(AnnualMeetingoftheAssociationforComputationalLinguistics)近十年研究热点追踪ACL近10年研究热点追踪......
  • FastAPI 应用安全加固:HTTPSRedirectMiddleware 中间件全解析
    在当今的网络环境中,数据安全变得越来越重要。HTTPS作为一种安全协议,它通过加密传输数据来保护用户信息免受窃取和篡改。在FastAPI应用中,确保所有的HTTP请求都通过HTTPS进行是至关重要的。中间件在FastAPI中用于处理请求前后的通用任务,例如身份验证、日志记录、请......
  • HyperAI超神经 x Apache Pulsar | 9 月 22 日,北京 Pulsar Meetup 不见不散!
    PulsarMeetup北京2024PulsarMeetup北京2024活动将于2024年9月22日(周日)由谙流科技和小红书联合举办。诚邀Pulsar和各大社区的小伙伴、广大技术爱好者、架构师和企业代表参与。主办单位:AscentStream谙流科技、小红书活动时间:2024年9月22日14:00-18:00活......
  • fastapi middleware中间件
    一、介绍FastAPI中的中间件(Middleware)是一个非常重要的概念,它允许开发者在请求被处理之前和响应被发送之前执行自定义逻辑。中间件在Web应用程序中扮演着桥梁的角色,连接着客户端的请求和服务器端的响应处理过程。以下是FastAPI中间件概念的详细解释:1.中间件的定义在FastAPI中,......
  • 折半搜素(meet in the middle)
    算法介绍折半搜素通常用来处理数据规模不能直接通过暴力解决,但数据规模又没有特别大的情况。例如:[P10484送礼物](P10484送礼物-洛谷|计算机科学教育新生态(luogu.com.cn))题意:作为惩罚,GY被遣送去帮助某神牛给女生送礼物(GY:貌似是个好差事)但是在GY看到礼物之后,他就不......
  • 跟《经济学人》学英文:2024年08月24日这期 Apple can’t do cars. Meet the Chinese te
    Applecan’tdocars.MeettheChinesetechgiantsthatcanBaidu,HuaweiandXiaomihavebuiltthrivingautobusinesses原文:Ashescreechesaroundcornersatwildlyunsafespeeds,oneofthedesignersoftheJIDURobocar07calmlytalksyourcorrespo......
  • 题解:CF362A Two Semiknights Meet
    题意有两个走法为中国象棋象的棋子,棋盘上有一些坏格子,问它们是否可以在好格子相遇。思路则判断两个棋子是否相遇有两个条件是否可以在一个格子相遇。那个格子是否是好格子。先考虑条件\(1\)设第一个棋子的坐标为\(a_x\)和\(a_y\),第二个棋子的坐标为\(b_x\)和\(b_y......
  • 搜索之meet in middle(有效的小方法)
    题目:[https://www.luogu.com.cn/problem/P2962](P2962[USACO09NOV]LightsG)算法:meetinmiddle(折半搜索)思路:有\(35\)个点,总共的操作状态有\(2^{35}\)种情况。如果我们采用一般的搜索方式,时间上会毫不犹豫得爆掉。所以,我们要用折半搜索的方式。将所有的点拆分成两个集合,对......
  • 使用 addRouteMiddleware 动态添加中间
    title:使用addRouteMiddleware动态添加中间date:2024/8/4updated:2024/8/4author:cmdragonexcerpt:摘要:文章介绍了Nuxt3中addRouteMiddleware的使用方法,该功能允许开发者动态添加路由中间件,以实现诸如权限检查、动态重定向及路由变化时的特定操作。内容涵盖路由中间......