首页 > 其他分享 >折半搜索

折半搜索

时间:2023-09-18 18:11:07浏览次数:30  
标签:折半 return int dfs dfs1 搜索 mathbf

简介:

\(\mathbf{meet}\) \(\mathbf{in}\) \(\mathbf{the}\) \(\mathbf{middle}\) 是一种特殊的搜索技巧,利用了“折半”这种思想,先分别搜出两半子问题的答案,再利用总问题与子问题之间的关系进行合并,得出答案。

关于时间复杂度:

原问题的搜索往往是 \(\Theta(2^n)\) 复杂度,折半后复杂度同时折半,当然还要算上合并答案的复杂度(这类复杂度往往不会太高)。

练习:

世界冰球锦标赛

当然是 \(\mathbf{meet}\) \(\mathbf{in}\) \(\mathbf{the}\) \(\mathbf{middle}\) 的模板题,首先爆搜不用多说,考虑如何合并答案:我们将前后两半子问题的每种状态搜出来,再将前半段状态按照答案排序,利用 upper_bound 查出前驱进行统计。

code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=55,M=1<<21;
int n,m,w[N],mid,suma[M],sumb[M],cnta,cntb,ans;
void dfs(int l,int r,int sum,int a[],int &cnt){
    if(sum>m) return;
    if(l>r) return a[++cnt]=sum,void();
    dfs(l+1,r,sum+w[l],a,cnt);
    dfs(l+1,r,sum,a,cnt);
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>w[i];
    mid=n>>1;
    dfs(1,mid,0,suma,cnta);
    dfs(mid+1,n,0,sumb,cntb);
    sort(suma+1,suma+1+cnta);
    for(int i=1;i<=cntb;i++)
        ans+=upper_bound(suma+1,suma+1+cnta,m-sumb[i])-suma-1;
    cout<<ans;
    return 0;
}

期末考试

知道了 \(\mathbf{meet}\) \(\mathbf{in}\) \(\mathbf{the}\) \(\mathbf{middle}\) 这题就比较容易了,首先爆搜是平凡的,枚举每个状态一个一个对号就行,但是超时。因此考虑如何合并答案:我们为前半子问题的每一个答案开桶计数,对后半子问题的每个答案查 \(m-sum\) 即可,当然这 \(n\) 次的回答是统一的,不能分开统计,因此我们计算对于 \(n\) 次回答每个最终的得分并将这 \(n\) 个数哈希起来,统一考虑即可。

code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e4+10,p=1e9+7;
int n,ans(0),hast1(0);
int d[N],b[N][15],a[N];
map<int,int> mp;
void dfs(int x){
    if(x==6){
        int has(0);
        for(int i=1;i<=n;i++){
            int op=0;
            for(int j=1;j<=5;j++) if(d[j]==b[i][j]) op+=10;
            if(op>a[i]) return;
            has=(has*131%p+op)%p;
        }
        mp[has]++;
        return;
	}
	d[x]=1;dfs(x+1);
    d[x]=2;dfs(x+1);
	d[x]=3;dfs(x+1);
    d[x]=4;dfs(x+1);
}
void dfs1(int x){
    if(x==11){
	    int has(0);
        for(int i=1;i<=n;i++){
            int op=0;
            for(int j=6;j<=10;j++) if(d[j]==b[i][j]) op+=10;
            if(op>a[i]) return;
            has=(has*131%p+op)%p;
		}
		ans+=mp[(hast1-has+p)%p];
		return;
	}
	d[x]=1;dfs1(x+1);
    d[x]=2;dfs1(x+1);
	d[x]=3;dfs1(x+1);
    d[x]=4;dfs1(x+1);
}
char s[N][15];
signed main(){
    // freopen("1.in","r",stdin);
    ios::sync_with_stdio(false);
    // cin.tie(0),cout.tie(0);
    int T;cin>>T;
    while(T-->0){
        cin>>n;
        hast1=0;
        mp.clear();
        for(int i=1;i<=n;++i){
            for(int j=1;j<=10;++j) cin>>s[i][j];
            for(int j=1;j<=10;++j){
                if(s[i][j]=='A') b[i][j]=1;
                if(s[i][j]=='B') b[i][j]=2;
                if(s[i][j]=='C') b[i][j]=3;
                if(s[i][j]=='D') b[i][j]=4;
            }
            cin>>a[i];
            hast1=(hast1*131%p+a[i])%p;
        }
        ans=0;
        dfs(1);dfs1(6);
        cout<<ans<<endl;
    }
}

标签:折半,return,int,dfs,dfs1,搜索,mathbf
From: https://www.cnblogs.com/shen666zxcmt/p/17712726.html

相关文章

  • 优维低代码实践:图片和搜索
    优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。优维低代码实践连载第18期《图片和搜索》▽「图片」在一些编排场景下,会需......
  • 世界第5大搜索引擎Yandex爆出源码后获得的其内部若干排名因素
    相关新闻:中文翻译版:https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9394501005789721090%22%7D&n_type=-1&p_from=-1英文版:https://www.hackread.com/yandex-source-code-hacked-leaked/  =============================      ========......
  • 230. 二叉搜索树中第K小的元素
    给定一个二叉搜索树的根节点root,和一个整数k,请你设计一个算法查找其中第k个最小元素(从1开始计数)。示例1:输入:root=[3,1,4,null,2],k=1输出:1>代码classSolution{public:vector<int>res;intaaa;voidtraversal(TreeNode*root,intk){......
  • 【POJ 2488】A Knight‘s Journey 题解(深度优先搜索)
    背景骑士厌倦了一次又一次地看到同样的黑白方块,决定去旅行全世界每当骑士移动时,它是一个方向上的两个正方形和一个垂直于这个方向的正方形。骑士的世界就是他生活的棋盘。我们的骑士生活在一个棋盘上,这个棋盘的面积比普通的8*8棋盘小,但它仍然是矩形的。你能帮助这位冒险的骑士制......
  • 如何使用谷歌搜索的时候,不是从当前页面而是从新页面打开链接?
    参考链接:https://support.google.com/chrome/thread/3520860/how-do-i-set-chrome-to-open-links-in-a-new-tab-on-the-same-browser-window?hl=en1.使用ctrl+左键点击链接2.在Google主界面进行更改进入主界面https://www.google.com/webhp,点击下方的设置选择其中的搜索设置......
  • TienChin 渠道管理-渠道搜索
    ChannelController@PreAuthorize("hasPermission('tienchin:channel:list')")@GetMapping("/list")TableDataInfolist(ChannelVOchannelVO){startPage();List<Channel>list=iChannelService.selectChannelList(channe......
  • vim插件使用python编写+AXI非对齐传输如何发送+verdi配置搜索顺序+verible和verilator
    vim插件使用python编写虽然vim有自己的一套语法格式,但是学习成本放着呢,语言那么多,啥都学哪学的过来嘛。不过vim确实是支持python的,但是是python2,而不是python3,因此语法上的一些问题要兼容下。这个是官方手册,正确而可靠的部分。https://vimdoc.sourceforge.net/htmldoc/if_pyth......
  • 【UVA 572】Oil Deposits 题解(深度优先搜索)
    GeoSurvComp地质调查公司负责探测地下石油矿床。GeoSurvComp一次处理一个大的矩形土地区域,并创建一个划分将土地分割成许多方形地块。然后使用传感设备分别分析每个地块确定图中是否含有油。含有石油的地块称为口袋。如果两个口袋相邻,则它们是相同的油沉积。油沉积物可能非常......
  • 怎样才能让百度搜索到自己的博客?--九五小庞
    怎么把自己的博客推荐到百度、Google等主要搜索引擎?如果不把你的博客提交到各大搜索引擎中,它们一般是不会收录你的博客的,你可以先尝试一下看看能不能在百度搜到你的博客吧。如果搜不到的话说明你的博客还没有被百度收录,那么怎么才能被百度、google等各大搜索引擎收录你的博......
  • elasticsearch快照 备份和还原 可搜索快照
    快照是什么快照是从正在运行的Elasticsearch集群中获取的备份。可以针对整个集群拍摄快照,也可以针对整个集群的数据流和索引。也可以仅对集群中的特定数据流或索引进行快照。备份集群的唯一可靠且受支持的方法是拍摄快照。不可通过复制其节点的数据目录来备份Elasticsearch集群。......