当前位置: 首页 > news >正文

算法复盘——二分查找

一、思路

满足单调性 → 二分答案 → check 贪心验证 → 求最小 / 最大值

二、例题

1. 跳石头

P2678 [NOIP 2015 提高组] 跳石头 - 洛谷

题目核心:

1、起点0,终点L,中间有N块石头,位置已由小到大排序好

2、最多移走M块石头

3、目标是将最短跳跃的距离最大化

分析:

为何使用二分算法?

1、答案具有单调性:要求的距离越短所要移动的石头就越少;距离越远要求移动的石头也就越多。

2、从而构成了二段性,二分就是来找这个分段点的,即能否在移走 ≤M 块石头的前提下,让所有跳跃距离都 ≥mid

可行 可行 … 可行 | 不可行 不可行 …

代码实现:

#include <bits/stdc++.h> using namespace std; #define int long long const int N = 5e4 + 10; int n, L, a[N], m; int check(int mid) { int tmp = 0; for (int i = 0; i <= n; i++) { int j = i + 1; while(j <= n && a[j] - a[i] < mid) j++; //站在i往j跳 tmp += (j - i - 1); i = j - 1; } return tmp; } signed main() { cin >> L >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; a[++n] = L; int l = 1, r = L; while(l < r) { int mid = (l + r + 1) >> 1; if(check(mid) <= m) l = mid; else r = mid - 1; } cout << l<< endl; return 0; }

2. 木材加工

P2440 木材加工 - 洛谷

题目核心:

1、一共n块原木,每根原木长Li,要切割最终得到k段

2、目标是让最小的段尽可能大

分析:

单调性:长度越长,段数越少

代码实现:

#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e5 + 10; int n, k, a[N], lmax; int check(int mid) { int tmp = 0; for(int i = 1; i <= n; i++) tmp += a[i] / mid; return tmp; } signed main() { cin >> n >> k; for (int i = 1; i <= n; i++) { cin >> a[i]; lmax = max(lmax, a[i]); } if (check(1) < k) { cout << 0 << endl; return 0; } int l = 1, r = lmax; while(l < r) { int mid = (l + r + 1) >> 1; if(check(mid) >= k) l = mid; else r = mid - 1; } cout << l << endl; return 0; }

3. 分割数组最大值

410. 分割数组的最大值 - 力扣(LeetCode)

题目核心:

1、一个数组,要进行连续的分割,分割成k段

2、目标是让每段的和尽可能的小

分析:

单调性:候选值(每段和的上限)越大,每段所放入的元素就越多,分的段数就越少;反之亦然

代码实现:

class Solution { public: int splitArray(vector<int>& nums, int k) { // 左边界:数组最大值,右边界:数组总和 int left = *max_element(nums.begin(), nums.end()); int right = accumulate(nums.begin(), nums.end(), 0); // 二分查找 while (left < right) { int mid = left + (right - left) / 2; // 判断最大和为 mid 时,是否能分成 <=k 段 if (check(nums, mid) <= k) { // 可以满足 → 还可优化 → 尝试更小mid right = mid; } else { // 不满足 → 需要更大的值 left = mid + 1; } } return left; } int check(vector<int>& nums, int maxSum) { int count = 1; // 初始段数为 1 int curSum = 0; // 当前段的和 for (int num : nums) { curSum += num; if (curSum > maxSum) { // 超过上限,必须新开一段 curSum = num; count++; } } return count; } };

4.进击的奶牛

P1824 [USACO05FEB] 进击的奶牛 Aggressive Cows G - 洛谷

代码实现:

#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; int n, m, a[N]; int check(int mid) { int cnt = 1; int last = a[1]; for(int i = 2; i <= n; i++) { if(a[i] - last >= mid) { cnt++; last = a[i]; } } return cnt; } signed main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; sort(a + 1, a + 1 + n); int l = 1, r = a[n] - a[1]; while(l < r) { int mid = (l + r + 1) / 2; if(check(mid) >= m) l = mid; else r = mid - 1; } cout << l << endl; return 0; }

5.数列分段

P1182 数列分段 Section II - 洛谷

代码实现:

#include <bits/stdc++.h> using namespace std; #define int long long const int N = 1e5 + 10; int n, m; vector <int> a(N); int check(int mid) { int cnt = 1; int sum = 0; for(int i = 1; i <= n; i++) { sum += a[i]; if(sum > mid) { sum = a[i]; cnt++; } } return cnt; } signed main() { cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; int l = *max_element(a.begin() + 1, a.begin() + 1 + n); int r = accumulate(a.begin() + 1, a.begin() + 1 + n, 0LL); while(l < r) { int mid = l + (r - l) / 2; if(check(mid) <= m) r = mid; else l = mid + 1; } cout << l << endl; }
http://www.cnnetsun.cn/news/1551487.html

相关文章:

  • 卷积神经网络(CNN)原理与PyTorch 2.8实现:图像分类从入门到精通
  • DeepSeek-R1-Distill-Llama-8B功能体验:数学、代码、推理全搞定
  • 手把手教你:在无外网Linux服务器上,用Ollama离线部署CodeQwen-7B大模型(附Modelfile避坑指南)
  • N_m3u8DL-RE完全指南:3分钟解决流媒体下载难题的终极方案
  • 告别Keil!在Ubuntu 20.04上用Eclipse搭建GD32开发环境(保姆级图文教程)
  • 无人机国标协议接入故障深度分析与系统性解决方案
  • 百川2-13B-4bits量化版效果展示:JSON格式返回、表格对比、Markdown代码块原生支持
  • GLM-OCR文件处理进阶:C语言实现批量图片读取与识别结果输出
  • 终极番茄小说下载器:Rust重构的高效电子书下载解决方案
  • 基于Matlab的语音信号加密解密传输系统:支持GUI界面与自定义密码保护
  • YOLOv9镜像快速上手:一行命令跑通推理,小白也能玩转目标检测
  • 3分钟上手!AI驱动的代码学习助手完全指南
  • Qwen2-VL-2B-Instruct应对“耦合过度”设计:从UML图中识别代码坏味道
  • 基于DWS构建RAG框架生成行业调研报告
  • PMSM无感ActiveFlux仿真模型:基于电流误差补偿的相电压重构与延时相角补偿技术实现及...
  • RCS调度系统:从架构蓝图到智能决策的AGV指挥中枢
  • FastAPI 2.0异步流式AI服务上线前必做的7项压力测试:并发流数、断连重试率、token吞吐拐点、内存增长斜率…(附自动化测试脚本)
  • 架构革新与纯粹体验:铜钟音乐平台的现代Web音频解决方案
  • 手机玩转Kali必看:Termux环境完整避坑指南(含文件校验/环境变量设置)
  • OpenClaw监控告警系统:Qwen3-32B-Chat实时日志分析
  • vLLM-v0.17.1技术解析:PagedAttention内存管理与显存优化技巧
  • Alpamayo-R1-10B详细步骤:从supervisorctl服务管理到日志实时监控
  • HY-Motion 1.0在医疗康复中的应用:患者动作评估与指导系统
  • 小白友好!Ollama部署GLM-4.7-Flash常见问题解决
  • M2LOrder模型实战:基于.NET框架的桌面端AI助手开发
  • AIGlasses OS Pro效果实测:纯本地视觉辅助系统,四大模式惊艳展示
  • 06_gstack发布运营:一键发布与文档同步机制
  • 如何通过md2pptx实现Markdown到PPT的高效转换与自动化办公
  • LabWindows/CVI文本框控件实战:从显示Hello World到动态时间更新
  • 构建边缘AI小语言模型