算法·二分

二分枚举

适用条件:

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

思维技巧

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

模板

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

以下均为题解

小鸟的设备

题目背景

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

题目描述

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

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

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

输入格式

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

接下来 nn 行,每行表示一个设备,给出两个整数,分别是这个设备的 aia_ibib_i

输出格式

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

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

设你的答案为 aa,标准答案为 bb,只有当 a,ba,b 满足
abmax(1,b)104\dfrac{|a-b|}{\max(1,b)} \leq 10^{-4} 的时候,你能得到本测试点的满分。

解题思路

  • 注意题目描述:能量的使用是连续的,意味着可以从整体来看问题,如果充电量大于总耗电量,则一定可以无限使用,反之则不能。
  • 直接表达问题非常困难,但是从枚举的角度验证答案其实不难
  • 注意精度
#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 需要砍 MM 米长的木材。对 Mirko 来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍伐森林。不过,Mirko 只被允许砍伐一排树。

Mirko 的伐木机工作流程如下:Mirko 设置一个高度参数 HH(米),伐木机升起一个巨大的锯片到高度 HH,并锯掉所有树比 HH 高的部分(当然,树木不高于 HH 米的部分保持不变)。Mirko 就得到树木被锯下的部分。例如,如果一排树的高度分别为 20,15,1020,15,101717,Mirko 把锯片升到 1515 米的高度,切割后树木剩下的高度将是 15,15,1015,15,101515,而 Mirko 将从第 11 棵树得到 55 米,从第 44 棵树得到 22 米,共得到 77 米木材。

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

输入格式

1122 个整数 NNMMNN 表示树木的数量,MM 表示需要的木材总长度。

22NN 个整数表示每棵树的高度。

输出格式

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

解题思路

  • 正常的二分
  • 枚举+最大
#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

题目描述

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

关于最大值最小:

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

将其如下分段:

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

第一段和为 66,第 22 段和为 99,第 33 段和为 11,和最大值为 99

将其如下分段:

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

第一段和为 44,第 22 段和为 66,第 33 段和为 66,和最大值为 66

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

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

输入格式

11 行包含两个正整数 N,MN,M

22 行包含 NN 个空格隔开的非负整数 AiA_i,含义如题目所述。

输出格式

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

解题思路

  • 判定函数:我感觉我的判定函数没起到作用,因为当区间长度为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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

微信如何快速回复信息呢?

时业务繁忙的时候可能会出现一大堆消息需要去回复&#xff0c;很多客户也会来问重复的问题&#xff0c;有时候回复消息也需要一个及时性&#xff0c;如果回复慢了有可能客户就跑了&#xff0c;那这个时候就会体现出自动回复的优势。 只要设置好一个关键词&#xff0c;只要对方…

基于React 实现井字棋

一、简介 这篇文章会基于React 实现井字棋小游戏功能。 二、效果演示 三、技术实现 import {useEffect, useState} from "react";export default (props) > {return <Board/> }const Board () > {let initialState [[, , ], [, , ], [, , ]];const [s…

【CW32F030CxTx StartKit开发板】利用超声波传感器实现智能灯控

目录 1、超声波传感器 2、硬件连线 3. 程序开发 3.1 超声波测距 3.2 LED控制 4. 演示视频 本文首发于21ic。 感谢21ic和武汉芯源提供的测试机会。 在上一篇帖子中介绍了CW32F030CxTxStartKit 评估板的环境构建。本次介绍如何利用超声波传感器实现人来灯亮&#xff0c;人…

Milvus lite start 及存储策略

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

合并pdf的方法,如何合并pdf文件到一个pdf,简单方法

在现代办公和学习中&#xff0c;pdf格式的文件因其跨平台兼容性和安全性得到了广泛应用。然而&#xff0c;有时我们需要将多个pdf文件合并成一个&#xff0c;以便于管理和分享。本文将详细介绍几种合并pdf的方法&#xff0c;帮助读者轻松完成pdf文件的合并工作。 方法一、使用p…

【NLP学习路线的总结】

🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 目录 0. 👉前言1. 👉前置知识👉基础数学知识👉编程语言👉…

matlab:对带参数a关于x的方程求解

题目 讲解 简洁对各个式子的内部含义用浅显易懂的话语总结出来了&#xff0c;耐心体会 f(a) (x)exp(x)x^ax^(sqrt(x))-100;%因为下面的fzero的第一个数需要一个fun&#xff0c;所以这里有两个句柄&#xff0c;第一个a是输入的&#xff0c;第二个x是需要被解出的 A0:0.1:2;%创…

12种增强Python代码的函数式编程技术

前言 什么是函数式编程&#xff1f; 一句话总结&#xff1a;函数式编程(functional programming)是一种编程范式&#xff0c;之外还有面向对象&#xff08;OOP&#xff09;、面向过程、逻辑式编程等。 函数式编程是一种高度抽象的编程范式&#xff0c;它倡导使用纯函数&#x…

VTD的RDB介绍,从入门到放弃

文章目录 前言一、二、常见的RDB数据类型1、RDB_OBJECT_STATE_BASE_t2、RDB_OBJECT_STATE_EXT_t3、RDB_OBJECT_STATE_t4、RDB_SENSOR_OBJECT_t5、RDB_COORD_t6 RDB_GEOMETRY_t7、RDB_MSG_ENTRY_HDR_t 三、疑惑的问题点&#xff1a;1、在RDB_OBJECT_STATE_EXT_t中这两个的区别是…

前端面试题26(vue3中响应式实现原理)

Vue 3 中响应式系统的实现主要依赖于 ES6 的 Proxy 对象&#xff0c;这与 Vue 2 中使用 Object.defineProperty 的方式有着本质的区别。Proxy 提供了一种更为强大且灵活的方法来拦截和定制对象的操作&#xff0c;例如获取、设置属性值等。下面是对 Vue 3 响应式系统实现方式的详…

5款好用公司监控软件分享|管理者必看

当今社会&#xff0c;企业数据安全和员工工作效率成为了管理者不可忽视的重要议题。 选择合适的公司监控软件&#xff0c;不仅有助于提升管理效率&#xff0c;还能有效保障企业信息安全。 下面小编将为您分享五款备受好评的公司监控软件&#xff0c;助力管理者更好地管理企业…

faskapi好用的模板

在Web开发领域&#xff0c;FastAPI作为一个基于Python的高性能Web框架&#xff0c;因其快速、易用以及强大的功能而备受开发者青睐。关于FastAPI的好用模板&#xff0c;这里介绍几个不同角度的模板或项目框架&#xff0c;以帮助您更好地理解和选择适合自己的起点。 1. FastAPI…

《基于 Kafka + Flink + ES 实现危急值处理措施推荐和范围校准》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;欢迎多多交流。&am…

.locked勒索病毒解析与防护指南

引言 随着信息技术的飞速发展&#xff0c;网络安全问题日益严峻&#xff0c;其中勒索病毒成为威胁企业和个人数据安全的重要隐患之一。在众多勒索病毒家族中&#xff0c;.locked勒索病毒以其独特的加密方式和广泛的传播途径&#xff0c;引起了广泛的关注。本文将从多个方面详细…

张量分解(1)——初探张量

&#x1f345; 写在前面 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;这里是hyk写算法了吗&#xff0c;一枚致力于学习算法和人工智能领域的小菜鸟。 &#x1f50e;个人主页&#xff1a;主页链接&#xff08;欢迎各位大佬光临指导&#xff09; ⭐️近…

解决线程不安全问题的几种方式

线程不安全问题 日常生活中我们会经常碰到在不同的平台上买各种票的问题&#xff0c;例如在App、线下售票窗口等购买火车票、电影票。这里面就存在着线程安全的问题&#xff0c;因为当多个线程访问同一个资源时&#xff0c;会导致数据出错&#xff0c;例如甲和乙两人同时看中了…

2024最新版若依-RuoYi-Vue3-PostgreSQL前后端分离项目部署手册教程

项目简介: RuoYi-Vue3-PostgreSQL 是一个基于 RuoYi-Vue3 框架并集成 PostgreSQL 数据库的项目。该项目提供了一套高效的前后端分离的开发解决方案&#xff0c;适用于中小型企业快速构建现代化的企业级应用。此项目结合了 RuoYi-Vue-Postgresql 和 RuoYi-Vue3 的优点&#xff0…

libaom 编码器实验 AV1 标准 SVC 分层编码

SVC编码 视频SVC编码&#xff0c;即Scalable Video Coding&#xff08;可适性视讯编码或可分级视频编码&#xff09;&#xff0c;是H.264/MPEG-4 AVC编码的一种扩展&#xff0c;它提供了更大的编码弹性&#xff0c;并且具有时间可适性&#xff08;Temporal Scalability&#x…

React Hooks:上天在提醒你,别再用Class组件了!

React Hooks&#xff1a;上天在提醒你&#xff0c;别再用Class组件了&#xff01; React Hooks 的出现可以说是前端界的一场革命。它不仅让我们告别了繁琐的 Class 组件&#xff0c;还让代码变得更加简洁、易读、易维护。如果你还在固守 Class 组件的阵地&#xff0c;那么这篇…

vue3项目实战中的接口调用

vue项目组成 一个项目往往由这几个部分组成。&#x1f447;&#x1f447; 其中在src文件夹中的内容如下&#x1f447;&#x1f447; 我们常常将接口文件&#xff0c;新建在文件夹src下&#xff0c;一般命名为api&#xff0c;api内的文件便是接口文件。&#x1f447;&#x1f4…