折半搜索-oier复健练习题目

2023-10-21 19:13

本文主要是介绍折半搜索-oier复健练习题目,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法介绍:

折半搜索常用于复杂度O(n!)级的搜索问题,当我们发现很显然可以将问题划分为两部分分别搜索枚举,再合二为一求出最终答案时,我们可以选择使用折半搜索。

常见数据规模:

对于答案的值域往往没有要求,只对给出元素个数 n n n 有一定要求:

n ≤ 50 n\leq50 n50

例题:

来源:东BOJ:oj.neu.edu.cn

在这里插入图片描述

解题思路:

设目标值x为 g o a l goal goal,最终种类数为 a n s ans ans

如果纯暴力解决,算法复杂度为 O ( 2 n ) O(2^n) O(2n),而 n n n最大可达到 40 40 40,显然是会超时的

所以我选择先枚举出前半部分元素,即 t 1 ∼ t n / 2 {t_1} \sim {t_{n/2}} t1tn/2所能生成的所有值 t o t 1 tot_1 tot1所组成的集合 s s s

再去搜索 t n / 2 + 1 ∼ t n {t_{n/2+1}} \sim {t_{n}} tn/2+1tn能组合产生的所有的值 t o t 2 tot_2 tot2,对于每次搜索产生的 t o t 2 tot_2 tot2,都去 s s s中二分搜索出 x − t o t 2 x-tot_2 xtot2的值,如果 x − t o t 2 x-tot_2 xtot2存在,就是找到可行方案了,It’s MYGO!, 就把 t y p e [ x − t o t 2 ] type[x-tot_2] type[xtot2]加到最终答案 a n s ans ans中。

如果没有找到,就不是可行方案,乐队就要解散了(大悲)

关于我曲折的debug过程

最开始是 T L E TLE TLE,这很正常,毕竟 s s s规模还是挺大的,硬搜肯定会 T T T掉。
显然优化就是 u n i q u e unique unique去重,然后统计 s s s每个元素的出现次数。
结果还是过不了,一堆 W A WA WA
心态就彻底炸了
这题都做不出来是不是该速速remake了
胃疼头疼的debuff就一起上了。
最后发现,是 u n i q u e unique unique写错了…
本来我定义的 s s s大小是 c n t cnt cnt,实际我给写成 n n n了…

正确代码:
在这里插入图片描述

错误代码
在这里插入图片描述

无话可说。。。。总之最后是过了,还算不错

完整代码

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e6+60;
long long si[maxn];
int cnt,n;
long long a[50],goal;
long long tot1=0,tot2=0;
long long minn;
long long type[maxn];
int len=0;
void dfs1(int x)
{if(x==n/2+1){si[++cnt]=tot1;return;}tot1+=a[x];if(tot1<=goal) dfs1(x+1);tot1-=a[x];dfs1(x+1); 
}
long long ans=0;
int ans_id=0;
bool jud(long long res)
{int l=1,r=len;while(l<r){int mid=(l+r+1)>>1;if(si[mid]==res){ans_id=mid;return true;}if(si[mid]<=res) l=mid;else r=mid-1;}return false;/*for(int i=1;i<=cnt;++i) {if(si[i]==res) ++ans;	}return false;*/
}
void dfs2(int x)
{if(x==n+1){if(tot2==goal) ans+=type[1];else if(jud(goal-tot2)) ans+=type[ans_id];return;}tot2+=a[x];if(tot2+minn<=goal) dfs2(x+1);tot2-=a[x];dfs2(x+1);
}		
int main()
{scanf("%d%lld",&n,&goal);for(int i=1;i<=n;++i)  scanf("%lld",&a[i]);dfs1(1);minn=si[1];for(int i=2;i<=cnt;++i) minn=min(minn,si[i]);sort(si+1,si+cnt+1);long long now=si[1];long long cnt_now=1;len=0;for(int i=2;i<=cnt;++i){if(si[i]==now) ++cnt_now;else{type[++len]=cnt_now;now=si[i];cnt_now=1;	}}type[++len]=cnt_now;unique(si+1,si+cnt+1)-si-1;dfs2(n/2+1);printf("%lld\n",ans);
//	printf("len=%d\n",len);
//	for(int i=1;i<=len;++i) printf("%d ",type[i]);return 0;	
}
/*
4 2
1 1 1 1
*/

题都看完了,就来推一首MYGO翻唱吧

【歌ってみた】少女レイ(少女REI) covered by 燈

一首不够?再来一个吧

【歌ってみた】「二息歩行 (Reloaded)」covered by 燈

这篇关于折半搜索-oier复健练习题目的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C# ComboBox下拉框实现搜索方式

《C#ComboBox下拉框实现搜索方式》文章介绍了如何在加载窗口时实现一个功能,并在ComboBox下拉框中添加键盘事件以实现搜索功能,由于数据不方便公开,作者表示理解并希望得到大家的指教... 目录C# ComboBox下拉框实现搜索步骤一步骤二步骤三总结C# ComboBox下拉框实现搜索步骤一这

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

题目1254:N皇后问题

题目1254:N皇后问题 时间限制:1 秒 内存限制:128 兆 特殊判题:否 题目描述: N皇后问题,即在N*N的方格棋盘内放置了N个皇后,使得它们不相互攻击(即任意2个皇后不允许处在同一排,同一列,也不允许处在同一斜线上。因为皇后可以直走,横走和斜走如下图)。 你的任务是,对于给定的N,求出有多少种合法的放置方法。输出N皇后问题所有不同的摆放情况个数。 输入

题目1380:lucky number

题目1380:lucky number 时间限制:3 秒 内存限制:3 兆 特殊判题:否 提交:2839 解决:300 题目描述: 每个人有自己的lucky number,小A也一样。不过他的lucky number定义不一样。他认为一个序列中某些数出现的次数为n的话,都是他的lucky number。但是,现在这个序列很大,他无法快速找到所有lucky number。既然

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m