折半搜索(meet in the middle)

折半搜索(meet in the middle)

? 我们经常会遇见一些暴力枚举的题目,但是由于时间复杂度太过庞大不得不放弃.

? 由于子树分支是指数性增长,所以我们考虑将其折半优化;

前言

? 这个知识点曾经在模拟赛中出现过,所以这里稍微提一下;

? 讲的很浅显,但是不要D讲者;

入门

? dfs搜索树是指数性增长,如果将指数减少一半,就将会有量的飞跃,所以在遇见暴力枚举太大时,我们可以考虑这种算法;

? 总体思想即,dfs搜素通常从一个点出发,遍历所有深度,那么我们考虑将深度减半,从两个点出发,然后分别统计两边dfs时的信息,整合即可;

注意

? 该算法能否使用的关键是整合,两个深度是否能整合在一起需要思考;

了解

? 我们通过一道例题来讲解;

? 有一个体积为 \(m\) \((m<=1e18)\) 的背包,有 \(n\) \((n<=40)\) 个物品,问装背包有多少种方案.

? 若 \(m\) 较小时,该题即一个裸的背包,但本题 \(m<=1e18\) 背包就会不可做 (我不会) ;

? 那么考虑最基础的方法,暴力枚举每一种情况,然后统计即可.

? 直接枚举会导致超时,我们可以考虑双向搜索,将物品截半,将第一次搜索时的情况存下来,排序,第二次搜索时,找到一个结果,二分查找第一次的情况,计数即可;

?

给 \(n\) \((n<=20)\) 个数,从中任意选出一些数,使这些数能分成和相等的两组。

求方案数.

? 我们同样考虑两遍dfs,分别整理出两次搜索的结果,但是整合时有些麻烦;

? 整合时,我们可以暴力计数,考虑到这些数的随机性,所以期望得分 \(100\) ,但是如果出题人精心手造数据,就会有些凉凉;

? 考虑每种情况只会有 \(1\) 的贡献,那么我们将 \(2^{20}\) 种情况分别跑出来,用两次dfs储存的结果判断是否可行即可;

总结

? 我们面对一些其他算法很难处理的问题,要留住我们的本心 (根) ,优化暴力搜索,也许也会得到一个不错的复杂度.

原文地址:https://www.cnblogs.com/waterflower/p/11842561.html

时间: 2024-10-02 22:33:28

折半搜索(meet in the middle)的相关文章

折半搜索

折半搜索 (meet in the middle) /* reference: translation: solution: trigger: note: * date: 2019.09.04 */ #include<bits/stdc++.h> using namespace std; #define int long long #define rep(i,a,b) for(int i=a;i<=b;++i) #define dwn(i,a,b) for(int i=a;i>=b

「10.13」毛一琛(meet in the middle)&#183;毛二琛(DP)&#183;毛三琛(二分+随机化???)

A. 毛一琛 考虑到直接枚举的话时间复杂度很高,我们运用$meet\ in\ the\ middle$的思想 一般这种思想看似主要用在搜索这类算法中 发现直接枚举时间复杂度过高考虑枚举一半另一半通过其他算法统计,保证两边互不影响 今天的题我们考虑枚举先枚举左半部分,然后每个物品有三种取值情况 选入A集合,选入B集合,不选,系数不同 考虑完左半部分再去考虑右半部分,那么我们可以用哈系表先从将左半部分的答案统计出来 然后右半部分查询他的相反数注意去重 也可以用将两边状态都用结构体存下来 注意去重 思

E. Anya and Cubes (CF #297 (Div. 2) 折半搜索)

E. Anya and Cubes time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Anya loves to fold and stick. Today she decided to do just that. Anya has n cubes lying in a line and numbered from 1 to n

算法复习——哈希表+折半搜索(poj2549)

搬讲义~搬讲义~ 折半搜索感觉每次都是打暴力时用的啊2333,主要是用于降次··当复杂度为指数级别时用折半可以减少大量复杂度··其实专门考折半的例题并不多···一般都是中途的一个小优化··· 然后折半搜索常常与哈希表一起使用··尤其是遇到方程类的问题时··· 哈希表就不说了吧···毕竟比较简单···不懂得看下面题的代码就行了,一道折半与哈希表联合运用的经典方程模型题··· Description Given S, a set of integers, find the largest d suc

FZU 2178 礼物分配 (折半搜索+二分)

题目地址:FZU 2178 由于n最大是30,一次全搜的话妥妥的超时,那么可以采用折半搜索.分成相同的两份,对左边的一堆进行预处理,然后再处理右堆,每一次都对左堆进行二分,找最接近的.由于两个人取的不能相差多于1个,所以要对每个个数分开存储.并排序,排序是为了后边的二分. 代码如下: #include <iostream> #include <string.h> #include <math.h> #include <queue> #include <

位运算符 优先级 折半搜索

看编程珠玑,深知二分搜索的用处之大,自己写了一遍,竟然出了死循环.代码如下: 1 int bsearch(int *data, int val,int left, int right) 2 { 3 if(left <= right) 4 { 5 int mid = left + (right-left)>>1; 6 if(data[mid]==val) 7 return mid; 8 else if(data[mid]<val) 9 return bsearch(data,val,

【bzoj4800】[Ceoi2015]Ice Hockey World Championship 折半搜索

题目描述 有n个物品,m块钱,给定每个物品的价格,求买物品的方案数. 输入 第一行两个数n,m代表物品数量及钱数 第二行n个数,代表每个物品的价格 n<=40,m<=10^18 输出 一行一个数表示购买的方案数 (想怎么买就怎么买,当然不买也算一种) 样例输入 5 1000 100 1500 500 500 1000 样例输出 8 题解 裸的折半搜索meet-in-the-middle 由于直接爆搜肯定会TLE,考虑把整个序列分成左右两部分,对于每部分求出它所有可以消耗钱数的方案.然后考虑左右

Codeforces#498F. Xor-Paths(折半搜索)

time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output There is a rectangular grid of size n×mn×m. Each cell has a number written on it; the number on the cell (i,ji,j) is ai,jai,j. Your task is

子集(状态压缩)(meet in the middle)

子集 [问题描述] R 君得到了?个集合,???共有 n 个正整数. R 君对这个集合很感兴趣. R 君通过努?钻研,发现了这个集合?共有 2n 个子集. 现在 R 君又对这个集合的?集很感兴趣. 定义?个集合的权值是这个集合内所有数字的和的话. 那么 R 君想问问你,这个集合的权值第 K小子集是多?. ps. 涉及到较少数字的 long long 输?输出,建议使用 cin/cout. [输入格式] 第??两个正整数 n,k. 接下来一行 n 个正整数,表?集合内元素. [输出格式] 输出?个