一本通题解——1436:数列分段II
题目链接
一本通OJ:http://ybt.ssoier.cn:8088/problem_show.php?pid=1436。
我的OJ:http://47.110.135.197/problem.php?id=4461。
题目
题目描述
对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小。
关于最大值最小:
例如一数列4 2 4 5 1要分成3段
将其如下分段:
[4 2][4 5][1]
第一段和为6,第2段和为9,第3段和为1,和最大值为9。
将其如下分段:
[4][2 4][5 1]
第一段和为4,第2段和为6,第3段和为6,和最大值为6。
并且无论如何分段,最大值不会小于6。
所以可以得到要将数列4 2 4 5 1要分成3段,每段和的最大值最小为6。
输入
第1行包含两个正整数N,M,第2行包含N个空格隔开的非负整数A[i],含义如题目所述。
输出
仅包含一个正整数,即每段和最大值最小为多少。
样例输入
5 3
4 2 4 5 1
样例输出
6
数据范围
N ≤ 1000,000,M ≤ N,1 ≤ Ai ≤ 1000000。
P.S. 一本通 OJ 是没有给出数据范围,我是经过多次测试出的数据范围,主要是 N 的大小。
分析
题意分析
从题目的描述中,我们可以知道,需要从 max(A[i]) 到 中找到一个合适的长度,对数列 A 进行分段。自然想到使用二分查找。
使用输入样例,我们来模拟一下二分查找的过程。
left | right | mid | 分段情况 | 分析 |
5 | 16 | 10 | [4 2 4] [5 1] | 不满足题目要求,mid 偏大,要变小 |
5 | 9 | 7 | [4 2] [4] [5 1] | 满足题目要求,mid 可能偏小,要变大 |
5 | 6 | 5 | [4] [2] [4] [1] | 满足题目要求,mid 可能偏小,要变大 |
6 | 6 | 6 | [4 2] [4] [5 1] | 满足题目要求,mid 可能偏小,要变大 |
6 | 5 | 结束二分查找,最佳的答案是 6 。 |
算法思路
一个标准的二分查找模板。
二分查找
1、left = max(A[i]),right = sum(A[1], A[2], ......, A[n]) 这个数据范围,进行二分查找
2、以 mid 为每段和的最大值,也就是每次分段和都不能超过 mid。
3、如果分段数 cnt > m,说明这个 mid 偏小,那么 mid 还可以再大一点,也就是左边界(left)移动到 mid+1;如果分段数 cnt ≤ m,说明这个 mid 偏大,那么 mid 还可以再小一点,也就是右边界(right)移动到 mid-1。注意需要记录下这个 mid。
AC参考代码
#include <bits/stdc++.h>
using namespace std;const int MAXN = 1e6+2;
int data[MAXN];bool check(int x, int n, int m) {int cnt=1;int len=0;//当前长度for (int i=1; i<=n; i++) {if (len+data[i]<=x) {len += data[i];} else {cnt++;len = data[i];}}return cnt<=m;
}int main() {int n,m;cin>>n>>m;int i;int left=0;int right=0;for (i=1; i<=n; i++) {cin>>data[i];left = max(left, data[i]);right += data[i];}int mid;int ans;while (right>=left) {mid = left+((right-left)>>1);//按照mid为最大值分段进行分段处理if (true==check(mid, n, m)) {//满足题目要求,mid 可能偏小,要变大ans = mid;//记录下这个分段值right = mid-1;} else {//不满足题目要求,mid 偏大,要变小left = mid+1;}}cout << ans << endl;return 0;
}
一本通题解——1436:数列分段II相关推荐
- 二分答案二题-P1182数列分段II,P1873砍树
T1:P1182T1:P1182T1:P1182 数列分段SectionIISectionIISection II 评测记录:https://www.luogu.org/recordnew/lists ...
- 数列分段II(信息学奥赛一本通-T1436)
[题目描述] 对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列4 2 4 5 1要分成3段 将其如下分段: ...
- 洛谷P1182 数列分段Section II 二分答案
洛谷P1182 数列分段Section II 二分答案 题意:将 n 个 数 分为 m段 求一种方案,使这m段中最大的和 最小 额..可能有点拗口,其实就是说每一种方案,都有对应的 每段和的最大值, ...
- 【二分】数列分段(ybtoj 二分-1-1)
数列分段 ybtoj 二分-1-1 题目大意 给出一个序列A,让你把它分成m段,使每段和最大值最小 输入样例 5 3 4 2 4 5 1 输出样例 6 数据范围 1⩽M⩽N⩽1051\leqslant ...
- CCF201509-1 数列分段
试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? 输入格式 ...
- P1181 数列分段Section I
传送门:洛谷 P1181 数列分段 AC的代码如下: #include<iostream> #include<cstdio> using namespace std; int ...
- CCF201509-1 数列分段(100分)【序列处理】
试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? ...
- CCF201509-1 数列分段(100分)
试题编号: 201509-1 试题名称: 数列分段 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? ...
- ccf试题1:数列分段
ccf试题1:数列分段 题目 分析 代码 总结 题目 问题描述 给定一个整数数列,数列中连续相同的最长整数序列算成一段,问数列中共有多少段? 输入格式 输入的第一行包含一个整数 ...
- *7-1 CCF 2015-09-1 数列分段
数列分段 题目描述 源代码 关于这题 题目描述 源代码 #include<iostream> using namespace std; int main() {int n, last, c ...
最新文章
- 一群算法_树遍历解释:他们就像一群懒惰的学生,试图欺骗他们的考试
- HSSFWorkbook 与 XSSFWorkbook
- SpringMVC + MyBatis整合 【转】
- 快讯!Sharding-Sphere正式进入Apache孵化器
- slope one 推荐算法python 代码_java和python实现一个加权SlopeOne推荐算法
- WPF异步载入图片,附带载入中动画
- WDS使用捕获映像制作企业自定义映像
- php读取excel类——PHP-ExcelReader
- Python 中使用help()命令后如何退出
- 从零开始学Pytorch(七)之卷积神经网络
- 51Nod 1002 数字三角形 Label:水水水 非学习区警告
- 使用pbrt遇到的问题及解决方法
- 常微分方程的近似计算和误差估计(2)
- f(x)的泰勒(Taylor)展开式
- JAVA开发短信验证码系统
- Part 1: 如何把Power BI 嵌入到sharepoint 网站
- (R语言)R的统计模型
- 运筹学基础【三】 之 决策
- 如何将pytorch模型部署到安卓
- docke的基础入门
热门文章
- 互联网行业的那些缩写PM,RD,FE,UE,QA,OP,BRD,MRD,PRD,FSD
- Vulnhub靶机:Homeless
- 各种程序员的工作内容
- Ubuntu 下五笔拼音混合输入法
- python 题目 给出一个整数数组 nums 和一个整数 k
- 基于K-means的彩色图像聚类之代码实现
- 带t2芯片的mac装linux,制作macOS系统盘超级简单,以及T2芯片的安装方法
- 数学分析 函数项级数(第13章)
- Spring validation框架简介
- 全球与中国电子柜锁市场深度研究分析报告