算法·二分

二分枚举

适用条件:

  • 答案有明显上下界
  • 答案具有单调性:a满足,若b>=a可以知b必定满足。
  • 本质上是枚举的对数优化

思维技巧

  • 解决问题->>验证答案,明显前者比后者更加困难
  • 若题目有最大值最小,最小值最大这种经典条件,隐含着答案有界

模板

  • 左边界和右边界的界定
  • 判定函数
  • 二分模板
bool isValid(){//验证答案
}
int l==a,r=b;
while(l<=r){int mid=(l+r)/2if(isValid(mid)){ans=mid;l=mid+1;}else{r=mid-1;}
}

以下均为题解

小鸟的设备

题目背景

小鸟有 n n n 个可同时使用的设备。

题目描述

i i i 个设备每秒消耗 a i a_i ai 个单位能量。能量的使用是连续的,也就是说能量不是某时刻突然消耗的,而是匀速消耗。也就是说,对于任意实数,在 k k k 秒内消耗的能量均为 k × a i k\times a_i k×ai 单位。在开始的时候第 i i i 个设备里存储着 b i b_i bi 个单位能量。

同时小鸟又有一个可以给任意一个设备充电的充电宝,每秒可以给接通的设备充能 p p p 个单位,充能也是连续的,不再赘述。你可以在任意时间给任意一个设备充能,从一个设备切换到另一个设备的时间忽略不计。

小鸟想把这些设备一起使用,直到其中有设备能量降为 0 0 0。所以小鸟想知道,在充电器的作用下,她最多能将这些设备一起使用多久。

输入格式

第一行给出两个整数 n , p n,p n,p

接下来 n n n 行,每行表示一个设备,给出两个整数,分别是这个设备的 a i a_i ai b i b_i bi

输出格式

如果小鸟可以无限使用这些设备,输出 − 1 -1 1

否则输出小鸟在其中一个设备能量降为 0 0 0 之前最多能使用多久。

设你的答案为 a a a,标准答案为 b b b,只有当 a , b a,b a,b 满足
∣ a − b ∣ max ⁡ ( 1 , b ) ≤ 1 0 − 4 \dfrac{|a-b|}{\max(1,b)} \leq 10^{-4} max(1,b)ab104 的时候,你能得到本测试点的满分。

解题思路

  • 注意题目描述:能量的使用是连续的,意味着可以从整体来看问题,如果充电量大于总耗电量,则一定可以无限使用,反之则不能。
  • 直接表达问题非常困难,但是从枚举的角度验证答案其实不难
  • 注意精度
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n;
double p,ans=0;
vector<double>e(100009, 0); //当前电力
vector<double>ct(100009, 0);//消耗bool isValid(double s,vector<double>e) {for (int i = 1; i <= n; i++) {e[i] -= ct[i] * s;}double sum = p * s;for (int i = 1; i <= n; i++) {if (e[i] < 0) {sum += e[i];}if (sum < 0) {return false;}}return true;
}
void solve() {cin >> n >> p;double sume = 0;//总电力double cost = 0;for (int i = 1; i <= n; i++) {cin >> ct[i] >> e[i];sume += e[i];cost += ct[i];}if (cost <= p) {cout << -1;return;}double time = sume / (cost - p);//最大时间//cout << "sume==" << sume << " cost==" << cost <<" time==" <<time<< endl;double l = 0, r = time;while (l <= r) {double mid = (l+r)/2;if (isValid(mid, e)) {ans = mid;l = mid + 1e-5;}else {r = mid - 1e-5;}}printf("%f", ans);}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

[COCI 2011/2012 #5] EKO / 砍树

题目描述

伐木工人 Mirko 需要砍 M M M 米长的木材。对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍伐森林。不过,Mirko 只被允许砍伐一排树。

Mirko 的伐木机工作流程如下:Mirko 设置一个高度参数 H H H(米),伐木机升起一个巨大的锯片到高度 H H H,并锯掉所有树比 H H H 高的部分(当然,树木不高于 H H H 米的部分保持不变)。Mirko 就得到树木被锯下的部分。例如,如果一排树的高度分别为 20 , 15 , 10 20,15,10 20,15,10 17 17 17,Mirko 把锯片升到 15 15 15 米的高度,切割后树木剩下的高度将是 15 , 15 , 10 15,15,10 15,15,10 15 15 15,而 Mirko 将从第 1 1 1 棵树得到 5 5 5 米,从第 4 4 4 棵树得到 2 2 2 米,共得到 7 7 7 米木材。

Mirko 非常关注生态保护,所以他不会砍掉过多的木材。这也是他尽可能高地设定伐木机锯片的原因。请帮助 Mirko 找到伐木机锯片的最大的整数高度 H H H,使得他能得到的木材至少为 M M M 米。换句话说,如果再升高 1 1 1 米,他将得不到 M M M 米木材。

输入格式

1 1 1 2 2 2 个整数 N N N M M M N N N 表示树木的数量, M M M 表示需要的木材总长度。

2 2 2 N N N 个整数表示每棵树的高度。

输出格式

1 1 1 个整数,表示锯片的最高高度。

解题思路

  • 正常的二分
  • 枚举+最大
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n,ans=0;
ll m; vector<int>v(1000009, 0);
bool isValid(int mid) {ll sum = 0;for (int i = 1; i <= n;i++) {if (mid > v[i]) {continue;}sum += (ll)(v[i] - mid);}if (sum >= m)return true;return false;
}
void solve() {cin >> n >> m;int maxlen = 0;for (int i = 1; i <= n; i++) {cin >> v[i];maxlen = max(v[i], maxlen);}int l = 0, r = maxlen;while (l <= r) {int mid = (l + r) / 2;/*cout << mid << endl;*/if (isValid(mid)) {ans = mid;l=mid+1;}else {r= mid - 1;}}cout << ans;
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

数列分段 Section II

题目描述

对于给定的一个长度为 N N N 的正整数数列 A 1 ∼ N A_{1\sim N} A1N,现要将其分成 M M M M ≤ N M\leq N MN)段,并要求每段连续,且每段和的最大值最小。

关于最大值最小:

例如一数列 4 2 4 5 1 4\ 2\ 4\ 5\ 1 4 2 4 5 1 要分成 3 3 3 段。

将其如下分段:

[ 4 2 ] [ 4 5 ] [ 1 ] [4\ 2][4\ 5][1] [4 2][4 5][1]

第一段和为 6 6 6,第 2 2 2 段和为 9 9 9,第 3 3 3 段和为 1 1 1,和最大值为 9 9 9

将其如下分段:

[ 4 ] [ 2 4 ] [ 5 1 ] [4][2\ 4][5\ 1] [4][2 4][5 1]

第一段和为 4 4 4,第 2 2 2 段和为 6 6 6,第 3 3 3 段和为 6 6 6,和最大值为 6 6 6

并且无论如何分段,最大值不会小于 6 6 6

所以可以得到要将数列 4 2 4 5 1 4\ 2\ 4\ 5\ 1 4 2 4 5 1 要分成 3 3 3 段,每段和的最大值最小为 6 6 6

输入格式

1 1 1 行包含两个正整数 N , M N,M N,M

2 2 2 行包含 N N N 个空格隔开的非负整数 A i A_i Ai,含义如题目所述。

输出格式

一个正整数,即每段和最大值最小为多少。

解题思路

  • 判定函数:我感觉我的判定函数没起到作用,因为当区间长度为1时,如果和sum>枚举值时,这个枚举值一定是无效的。
    但是如果不加入l=maxv对二分左边界作限制,又过不了…
  • 应该对二分边界作详细界定,不能忽略的左边界!!!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m,ans=0;
vector<int>v(100009, 0);
bool isValid(ll t,int m) {//t目标值,m是段数ll sum = 0;int i = 1;for (int j = 1; j <= n; j++) {sum += (ll)v[j];if (sum > t) {if (i < j) {sum = (ll)v[j];i = j;m--;}else {return false;}}}if (m < 1) {return false;}return true;
}
void solve() {cin >> n >> m;ll maxv = 0,sum=0;for (int i = 1; i <= n; i++) {cin >> v[i];maxv = max(maxv, (ll)v[i]);sum += (ll)v[i];}/*cout << "maxv==" << maxv <<" sum=="<<sum<< endl;*/ll l = maxv, r = sum,mid=0;while (l <= r) {mid = (l + r) / 2;if (isValid(mid, m)) {ans = mid;r = mid - 1;}else {l = mid + 1;}}cout << ans;
}
signed main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

烦恼的高考志愿

题目背景

计算机竞赛小组的神牛 V 神终于结束了高考,然而作为班长的他还不能闲下来,班主任老 t 给了他一个艰巨的任务:帮同学找出最合理的大学填报方案。可是 v 神太忙了,身后还有一群小姑娘等着和他约会,于是他想到了同为计算机竞赛小组的你,请你帮他完成这个艰巨的任务。

题目描述

现有 m m m 所学校,每所学校预计分数线是 a i a_i ai。有 n n n 位学生,估分分别为 b i b_i bi

根据 n n n 位学生的估分情况,分别给每位学生推荐一所学校,要求学校的预计分数线和学生的估分相差最小(可高可低,毕竟是估分嘛),这个最小值为不满意度。求所有学生不满意度和的最小值。

输入格式

第一行读入两个整数 m , n m,n m,n m m m 表示学校数, n n n 表示学生数。

第二行共有 m m m 个数,表示 m m m 个学校的预计录取分数。第三行有 n n n 个数,表示 n n n 个学生的估分成绩。

输出格式

输出一行,为最小的不满度之和。

样例 #1

样例输入 #1

4 3
513 598 567 689
500 600 550

样例输出 #1

32

思路

  • 二分枚举答案
  • 优化O(n*n)至O(nlogn)
  • 注意l=0,因为我排序了!!!下标从0开始了!!!!!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int m, n;
vector<ll>student(100009, 0);
vector<ll>school(100009, INT_MAX);
ll search(int target) {ll l = 0, r = m,mid=0;ll minval = INT_MAX;while (l <= r) {mid = (l + r) / 2;      if (school[mid] < target) {minval = min(minval, abs(school[mid] - target));l = mid + 1;}else if (school[mid] == target) {return 0;}else {minval = min(minval, abs(school[mid] - target));r = mid - 1;}}return minval;
}
void solve() {cin >> m >> n;for (int i = 1; i <= m; i++) {cin >> school[i];}for (int i = 1; i <= n; i++) {cin >> student[i];}sort(school.begin(), school.end());//排序后下标改变了!!!ll sum = 0;for (int i = 1; i <= n; i++) {sum += search(student[i]);}cout << sum;
}
signed main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/41970.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker-11☆ Docker Compose部署RuoYi-Cloud

一、环境准备 1.安装Docker 附:Docker-02-01☆ Docker在线下载安装与配置(linux) 2.安装Docker Compose 附:Docker-10☆ Docker Compose 二、源码下载 若依官网:RuoYi 若依官方网站 鼠标放到"源码地址"上,点击"RuoYi-Cloud 微服务版"。 跳转至G…

深入理解计算机系统 CSAPP 家庭作业8.22

书本知识够你写出答案,但是如果你想验证你写的答案,就要一些额外的东西.这本书很多题目都是如此 /** mysystem.c*/ #include <stdio.h> #include "csapp.h"int mysystem(char* command) {pid_t pid;int status;if ((pid Fork()) 0) {/*这里是关键用子程序去…

新加坡工作和生活指北:工作篇

文章首发于公众号&#xff1a;Keegan小钢 一年多以前&#xff08;2022 年 8 月初&#xff09;&#xff0c;那时我过来新加坡才 4 个多月&#xff0c;就写了篇文章分享了当时在新加坡的生活和工作体验。文章得到的反响不错&#xff0c;但也反馈出了一些新的问题&#xff0c;比如…

预训练对齐:数学理论到工程实践的桥梁

在人工智能和机器学习领域&#xff0c;预训练模型的对齐是一个至关重要的概念。本篇博客源自听了一场黄民烈老师关于大模型对齐的分享&#xff0c;整理内容如下&#xff0c;供大家参考。 数学理论中的预训练对齐 数学理论上&#xff0c;预训练对齐是什么&#xff1f; 序列…

Java-关键字(static,final)

1.1 static关键字 static关键字 : 静态的意思 , 可以修饰变量 , 也可以修饰方法 , 被static修饰的成员 , 我们叫做静态成员 static特点 : 静态成员被所类的所有对象共享 随着类的加载而加载 , 优先于对象存在 可以通过对象调用 , 也可以通过类名调用 , 建议使用类名 1. 静…

Keepalived+HAProxy 集群及虚IP切换实践

1、软件介绍 ①Keepalived keepalive是一个用c语言编写的路由软件&#xff0c;这个项目的主要目标是为Linux系统和基于Linux的基础设施提供简单而健壮的负载平衡和高可用性设施。负载均衡框架依赖于众所周知且广泛使用的Linux Virtual Server (IPVS)内核模块提供第4层负载均衡…

srs直播内网拉流带宽飙升问题记录

问题背景 srs部署在云服务器上&#xff0c;32核cpu&#xff0c;64G内存&#xff0c;带宽300M. 客户端从srs拉流&#xff0c;发现外网客户端拉流&#xff0c;cpu和带宽都正常。然而内网客户端拉流&#xff0c;拉流人数超过5人以上&#xff0c;带宽就会迅速飙升。 排查 用srs…

数学建模论文写作文档word

目录 1. 摘要写法1.1 确定题目与方法1.2 编写开头段落1.3 填写问题一1.4 重复步骤3填写其他问题1.5 编写结尾段落1.6 编写关键词 2. 问题重述2.1 问题背景2.2 问题提出 3. 问题分析4. 问题X模型的建立与求解5. 模型的分析5.1 灵敏度分析5.2 误差分析&#xff08;主要用于预测类…

Milvus lite start 及存储策略

背景 今天开始写下Milvus&#xff0c;为了方便&#xff0c;我直接使用的是 milvus-lite 版本&#xff0c;default 情况下&#xff0c;你可能不知道他到底将 db 存储到什么位置了。启动 default-server&#xff0c;看下Milvus 的start及存储逻辑 主逻辑 def start(self):sel…

adb参数详解

文章目录 1. -d2. -e3. -s4. -t5. -H6. -P7. -L8. --one-device9. --exit-on-write-error10. connect / disconnect11. pair12. forward13. forward --list14. reverse15. mdns check16. mdns services17. push18. pull19. sync20.shell21. install22. uninstall23. bugreport2…

最小二乘支持向量机(Least Squares Support Vector Machine,LSSVM)及其Python和MATLAB实现

LSSVM&#xff08;Least Squares Support Vector Machine&#xff09;又称最小二乘支持向量机&#xff0c;是支持向量机&#xff08;SVM&#xff09;的一种变体&#xff0c;它通过将SVM的优化问题转化为带约束的二次规划问题&#xff0c;利用最小二乘法进行优化求解&#xff0c…

redis集群部署 (通过redis工具快速部署,手动部署)

目录 一、快速部署集群 1、 进入集群目录&#xff0c;创建集群 2、 查看正常启动 二、部署集群 1、分配集群节点 2、验证集群可用性 3、停止redis进程 三、手动部署集群 1、配置redis.conf配置文件 2、启动redis集群 3、手动创建redis集群 4、验证 四、集群…

mysql异常数据损坏处理,报错:Operating system error number 2 in a file operation

一、问题描述 某次一线反应&#xff0c;某主库表全部丢失&#xff0c;查看为空&#xff0c;登陆主机查看mysqld.log后报错&#xff1a;Operating system error number 2 in a file operation数据目录OS重装后修改过&#xff0c;但只是指向方式不同&#xff0c;目录还是同一目录…

【绿色版】Mysql下载、安装、配置与使用(保姆级教程)

大家都知道&#xff0c;Mysql安装版的卸载过程非常繁琐&#xff0c;而且卸载不干净会出现许多问题&#xff0c;很容易让大家陷入重装系统的窘境。基于此&#xff0c;博主今天给大家分享绿色版Mysql的安装、配置与使用。 目录 一、Mysql安装、配置与使用 1、下载解压 2、创建…

vue对axios进行请求响应封装

一、原因 像是在一些业务逻辑上&#xff0c;比如需要在请求之前展示loading效果&#xff0c;或者在登录的时候判断身份信息&#xff08;token&#xff09;等信息有没有过期&#xff0c;再者根据服务器响应回来的code码进行相应的提示信息。等等在请求之前&#xff0c;之后做的一…

ABAP注释快捷键修改(留着备用)

ABAP注释快捷键修改(留着备用) 在使用ABAP编辑器的时候&#xff0c;原有的添加代码注释和取消代码注释的快捷键未生效&#xff0c;这时我们可以考虑对注释快捷键进行修改 在事务码SE38(ABAP编辑器)屏幕右下角&#xff0c;点击【Options选项】图标 在【键盘】|【命令】输入栏中…

DWM 相关实现代码 [自用]

1. DWM 缩略图和模糊隐藏实现半透明 #include <windows.h> #include <dwmapi.h> #include <string> #pragma comment(lib, "dwmapi.lib")// 检查 UWP 窗口是否可见 bool IsUWPWindowVisible(HWND hwnd) {DWORD cloaked 0;DwmGetWindowAttribute(…

【c语言】玩转文件操作

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C语言 目录 引言 一、文件的打开和关闭 1.流 2.标准流 3.文本文件和二进制文件 4.控制文件打开与关闭的函数 二、文件的顺序读写 三、文件的随机读写 1…

深入理解OAuth 2.0:原理、流程与实践

一、什么是OAuth 2.0 1. 什么是OAuth 2.0 OAuth 2.0 是一套关于授权的行业标准协议。 OAuth 2.0 允许用户授权第三方应用访问他们在另一个服务提供方上的数据&#xff0c;而无需分享他们的凭据&#xff08;如用户名、密码&#xff09;。 2. OAuth 2.0 应用场景 OAuth 2.0的…

非参数检测6——优缺点

优点&#xff1a; 参量检测的特点在于以似然比处理器为基础&#xff0c;并建立在假定干扰或噪声的统计特性已知的基础上。但实际上&#xff0c;干扰环境往往十分复杂&#xff0c;包括自然和人为因素&#xff0c;且常常随时改变。这使我们很难确定噪声的统计特性。因此人们提出…