【二分答案 C/C++】洛谷P1182 数列分段 Section II

2025 - 03 - 02 - 第 66 篇
Author: 郑龙浩 / 仟濹
【二分搜索/二分答案】

文章目录

  • 洛谷P1182 数列分段 Section II
    • 题目描述
    • 输入格式
    • 输出格式
    • 输入输出样例 #1
      • 输入 #1
      • 输出 #1
    • 说明/提示
    • 思路
    • 1 每段和的最大值最小 什么意思??
    • 2 大体思路
    • 代码

洛谷P1182 数列分段 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

输入 #1

5 3
4 2 4 5 1

输出 #1

6

说明/提示

对于 20 % 20\% 20% 的数据, N ≤ 10 N\leq 10 N10

对于 40 % 40\% 40% 的数据, N ≤ 1000 N\leq 1000 N1000

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 1 0 5 1\leq N\leq 10^5 1N105 M ≤ N M\leq N MN A i < 1 0 8 A_i < 10^8 Ai<108, 答案不超过 1 0 9 10^9 109

思路

看到本题,首先想到求的是最大值的最小化–>使用二分答案

解题核心:二分法寻找最小化段和最大值

1 每段和的最大值最小 什么意思??

这句话有点绕,我想了一阵子才明白什么意思,可能是我理解能力有限吧

意思其实很简单, 就是

  • 存在多种分法,每种分法会将数组分成多个段
  • 计算各段的和。在每种分法中,至少存在一段,其和为该分法中最大的和

2 大体思路

变量

M - 分段数量
num - 数字数量
arr - 数组vector
count - 实际分段数量
sum - 记录每一段的和
left - 左边界
right - 右边界
mid - 边界的中间值(待定答案)
  1. 范围(每段和的最大值的最小值)

    所有数中的最大值~所有数的和

    • 所有数中的最大值 - 最极端的一种情况就是分了好多段,但是就是有那么一段只有一个数字,这个数字还是这些段中最大的
    • 所有数的和 - 最极端的另一种情况就是所有数字就分一段,那么最大值也只能是这一段的和了

    注意,这个操作如果输入以后再单独运算又要循环,所以在输入的同时直接计算出 所有数中的最大值,所有数的和即可。

    left, right
    
  2. 使用二分答案去求解

    注意:刚开始段数就是1,就算是不分段,也是只有一段,默认cnt = 1

    • 范围 所有数中的最大值~所有数的和

    • check函数 - check( mid )

      sum每次对符合条件的元素累加,如果本次元素 + sum <= mid,表示没有达到或刚好等于设限的每段的和,可以继续加;如果本次元素 + sum > mid,则超过设限每段的和

      此时,分段数量要加一cnt ++,且新开一段,重新开始累加

      最后:

      段数<=设限段数 - 返回 1
      段数> 设限段数 - 返回 0

    1. 判断 check(mid)

    == 1,则表示段数 <= 设限段数,符合段数要求,可以尝试 更小的限制(更小的每段和最大值最小),使段数增多

    此时,应该将 右边界调小right = mid - 1

    == 0,则表示段数 > 设限段数,段数太多,必须要尝试 更大的限制(更大的每段和最大值最小),使段数减少

    此时,应该将 左边界调大left = mid + 1

    1. 最终确定下来 mid,打印即可

代码

// 洛谷P1182数列分段
// 2025-03-02
// 郑龙浩/仟濹
// 解题核心:二分法寻找最小化段和最大值
// M - 分段数量
// num - 数字数量
// arr - 数组vector
// ans - 存储答案
// count - 实际分段数量
// sum - 记录每一段的和
// left - 左边界
// right - 右边界#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int M, num; // 分段数量,数字数量
vector <int> arr; // 所有数字
// 变量
bool check( int mid ){int cnt = 1; // 当前分段数量(至少需要1段),即使没分,也是只有一段int sum = 0; // 记录每一段的和for (int i = 0; i < num; i++){if( arr[ i ] > mid ) return false;// 总和没有超过设限之和if( arr[ i ] + sum <= mid ){sum += arr[ i ];} else { // 总和超过设限之和 arr[ i ] + sum > mid sum = arr[ i ]; // 更新 sum,使其变为下一段的第一个数字,然后进入下一次循环,继续如上操作cnt ++;}}
//   >**段数<=设限段数 - 返回 1**
//   >**段数>  设限段数 - 返回 0**return cnt <= M;
}
int main( void ){cin >> num >> M; // 输入处理:注意N对应变量num(数列长度),M是目标分段数arr.resize(num); // 设置vector宽度int left = 0, right = 0; // 左右边界,初始左边界应为数组最大值,右边界为全部元素之和int mid; // 中间值(待定答案)int ans = 0; // 存储答案for( int i = 0; i < num; i ++ ){cin >> arr[ i ];if( left < arr[ i ] ) left = arr[ i ]; // 找出最大的数字,使左边界为最大值right += arr[ i ]; // 计算出所有数字之和,使有边界为所有数字之和}while ( left <= right ){mid = ( left + right ) / 2; // 中间值(待定答案)// 段数 <= M,表示课符合段数要求,可以尝试 更小的限制(更小的每段和最大值最小)**,使**段数增多**,// 此时,应该将 **右边界调小**,`right = mid - 1`if (check( mid )){ ans = mid;right = mid - 1;}// 若 `== 0`,则表示**段数 > 设限段数**,段数太多,必须要尝试 **更大的限制(更大的每段和最大值最小)**,使**段数减少**,// 此时,应该将 **左边界调大**,`left = mid + 1` else {left = mid + 1;}}cout << ans << endl;return 0;
}

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

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

相关文章

【大模型学习笔记】0基础本地部署dify教程

目录 一、准备工作1、安装包下载1.1 安装git1.2 安装docker&#xff08;1&#xff09;默认安装&#xff08;2&#xff09;自定义路径安装(推荐)1.3 验证docker1.4 切换镜像源 二、下载dify源码三、启动dify1、在docker目录下启动dify2、验证3、浏览器中输入 一、准备工作 本地…

unity pico开发 五 UI交互

文章目录 添加画布添加交互组件取消传送射线对UI的控制解决按扳机键会传送的冲突按下按键呼出菜单&#xff0c;并让菜单出现在头的前方 添加画布 创建一个新画布&#xff0c;添加一个Button&#xff0c;将画布改为world space&#xff0c;然后缩放改为0.001&#xff0c;调整到…

上海公共数据授权运营实践详解(政策制度、运营模式、运营平台、运营成果、场景案例)

近期&#xff0c;国家公共数据资源登记平台正式上线&#xff0c;将进一步推动公共数据授权运营加速推动。本期分享&#xff1a;上海市公共数据授权运营实践&#xff0c;上海公共数据授权运营为统一集中授权&#xff0c;上海数据集团作为上海公共数据授权运营的唯一单位&#xf…

HTTP超文本传输协议

HTTP超文本传输协议 HTTP的基本原理HTTP请求的组成HTTP响应的组成HTTP请求方法HTTP状态码HTTP的无状态性和持久连接HTTPS&#xff08;HTTP Secure&#xff09;Cookie 和 SessionCookieSession对比 总结 HTTP&#xff08;超文本传输协议&#xff09;是一种用于从Web服务器传输超…

android TabLayout设置tab的时候文字默认居中,选中文字加粗

1、前言如题 TabLayout设置tab的时候文字默认居中&#xff0c;在TabLayout布局增加以上代码。 tab选中文字加粗&#xff0c;需要重写TabLayout的customview进行设置。 app:tabMaxWidth"0dp" app:tabGravity"fill" app:tabMode"fixed"

二叉树专题练习 ——基于罗勇军老师的《蓝桥杯算法入门C/C++》

目录 一、B3642 二叉树的遍历 - 洛谷 算法代码&#xff1a; 1. 代码结构 头文件和命名空间&#xff1a; 常量定义&#xff1a; 结构体定义&#xff1a; 前序遍历函数&#xff1a; 中序遍历函数&#xff1a; 后序遍历函数&#xff1a; 主函数&#xff1a; 2. 代码思路…

健康饮食,健康早餐

营养早餐最好包含4大类食物&#xff1a;谷薯类&#xff1b;碳水&#xff1b;蛋白质&#xff1b;膳食纤维。 1.优质碳水 作用&#xff1a;提供持久的能量&#xff0c;避免血糖大幅波动等 例如&#xff1a;全麦面包、红薯&#x1f360;、玉米&#x1f33d;、土豆&#x1f954;、…

使用Linux服务器搭建。

前言&#xff1a; 本文将简述如何使用vmware模拟Linux搭建服务器环境。并配置相关安全措施。 本文工具&#xff1a; Centos Stream 9 图文详细安装记录_centos9安装教程详解-CSDN博客 xshell&#xff0c;服务器远程连接工具。 https://old.xp.cn/linux.html#install-show …

Artec Leo+Ray II 三维扫描仪成功为VR展数字化30吨重设备-沪敖3D

挑战&#xff1a;在贸易展上展示重达30吨的机械设备&#xff0c;同时克服设备搬运和展示的难题&#xff0c;减轻物流负担。。 解决方案&#xff1a;Artec Leo、Artec Ray II、Artec Studio、Blender、Unity、Microsoft HoloLens、HTC VIVE PRO 效果&#xff1a;在虚拟展厅中&am…

期权帮|如何判断股指期货市场是否值得做空呢?

锦鲤三三每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 如何判断股指期货市场是否值得做空呢&#xff1f; 如果你觉得市场下跌的可能性较大&#xff0c;那么就可以考虑做空股指期货。但记住&#xff0c;做空有风险&#xff0c;操作需…

qt实践教学(编写一个代码生成工具)持续更新至完成———

前言&#xff1a; 我的想法是搭建一个和STM32cubemux类似的图形化代码生成工具&#xff0c;可以把我平时用到的代码整合一下全部放入这个软件中&#xff0c;做一个我自己专门的代码生成工具&#xff0c;我初步的想法是在下拉选框中拉取需要配置的功能&#xff0c;然后就弹出对…

操作系统:计算机架构里的幕后指挥官

Linxu系列 文章目录 Linxu系列前言一、操作系统的概念二、操作系统的工作原理三、操作系统对软硬件资源的管理总结 前言 在上篇博客中&#xff0c;我们介绍了冯诺依曼体系&#xff0c;&#xff0c;但是冯诺依曼体系结构出现的都是硬件设备&#xff0c;难道需要用户去操作、管理…

DNS 详细过程 与 ICMP

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; DNS (Domain Name System) 快速了解&#x1f98b; DNS 背景&#x1f98b; 域名简介&#x1f98b; 真实地址查询 —— DNS&#x1f380; 域名的层级关系&am…

【C/C++算法】从浅到深学习--- 位操作算法(图文兼备 + 源码详解)

绪论&#xff1a;冲击蓝桥杯一起加油&#xff01;&#xff01; 每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 今天总结了下位操作中常见的使用的方法&#xff0c;并且附加许多训练&#xff0c;通过…

【每日八股】计算机网络篇(二):TCP 和 UDP

目录 TCP 的头部结构&#xff1f;TCP 如何保证可靠传输&#xff1f;1. 确认应答机制2. 超时重传3. 数据排序与去重4. 流量控制5. 拥塞控制6. 校验和 TCP 的三次握手&#xff1f;第一次握手第二次握手第三次握手 TCP 为什么要三次握手&#xff1f;问题一&#xff1a;防止历史连接…

Tomcat-web服务器介绍以及安装部署

一、Tomcat简介 Tomcat是Apache软件基金会&#xff08;Apache Software Foundation&#xff09;的Jakarta 项目中的一个核心项目&#xff0c;由Apache、Sun和其他一些公司及个人共同开发而成。 Tomcat服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用…

【通俗讲解电子电路】——从零开始理解生活中的电路(三)

实际应用案例&#xff1a;生活中的电子电路 ——拆解你身边的“隐形工程师” 1. 手电筒电路&#xff1a;最简单的直流系统 电路组成 电源&#xff1a;2节1.5V电池&#xff08;串联3V&#xff09;。 开关&#xff1a;按钮控制回路通断。 LED&#xff1a;发光二极管&#xff…

部署Windows Server自带“工作文件夹”实现企业网盘功能完整步骤

前文已经讲解过Windows Server自带的“工作文件夹”功能&#xff0c;现以Windows Server 2025为例介绍部署工作文件夹的完整步骤&#xff1a; 为了确保您能够顺利部署和充分利用工作文件夹的功能&#xff0c;我将按照以下步骤进行讲解。 请注意&#xff0c;在域环境中部署工作…

详解LSM树

目录 什么是LSM树 磁盘结构与顺序IO LSM树结构 LSM树的写入 SSTable合并 LSM树的读取 LSM树的删除 总结 什么是LSM树 LSM 树全名日志结构合并树&#xff08;Log-Structured Merge Tree&#xff09;&#xff0c;是一种用于存储和管理数据的树状数据结构&#xff0c;常用…

ABAP语言的动态编程(3) - data reference 对象

如果数据对象的类型在运行时才知道&#xff0c;就需要用到 data reference 对象。 Data references can point to any data objects or to their parts (components, rows of internal tables, or sections specified by offsets and lengths) 也就是说 data reference 对象其实…