题目描述

对于给定的一个长度为N的正整数数列 A1∼NA _{1∼N}A1∼N​,现要将其分成 M(M≤N)M(M≤N)M(M≤N)段,并要求每段连续,且每段和的最大值最小。

关于最大值最小:

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

将其如下分段:

[42][45][1][4\ 2][4\ 5][1][4 2][4 5][1]

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

将其如下分段:

[4][24][51][4][2\ 4][5\ 1][4][2 4][5 1]

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

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

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

输入格式

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

第 2 行包含 N 个空格隔开的非负整数 AiA_iAi​,含义如题目所述。

输出格式

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

输入输出样例

输入

5 3
4 2 4 5 1

输出

6

说明

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

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

对于 100%100\%100% 的数据,1≤N≤1051\leq N\leq 10^51≤N≤105 ,M≤NM\leq NM≤N,Ai<108A_i < 10^8Ai​<108, 答案不超过 10910^9109 。

思路分析(二分+贪心)

  1. 简化题目为:
    将 n 个数分成相邻的 m 组,每组元素都是连续的(同时也不能为空)。求在所有的分法中,使得每组和的 最大值最小的值是多少?

  2. 我们先想一个简单的问题:假定每组数和的最大值不超过v ,是否存在把数组分 为不多于m 段的方法? 不超过v 的前提下,每组数尽量多就行。

  3. 转换思路:每组数和最大值不超过v,求解至少分多少组。将这个值与 m 比较。 如果组数小于m组,则符合条件。假如蓝色是满足的v值,红色是不满足的,那交界处(v的最小值)就是我们要求的结果(每段和最大值最小)。

  4. 那么交界处的v值怎么求呢?二分

AC的C++代码

#include<iostream>
#include<algorithm>
using namespace std;int a[100005],n,m,le,ri,mid;//函数check判断v值是否满足条件
//返回值:若v满足条件,返回 1
bool check(int v)
{int num = 0,sum = 0;for(int i = 0;i < n;i++){if(sum+a[i] <= v)    // 组内所有数的和没有超过vsum += a[i];else   //若加上a[i]超过v,所以从a[i]开始重新算作新的一组 sum=a[i],num++;    }return num < m;
}int main()
{cin>>n>>m;for(int i = 0;i < n;i++){cin>>a[i];le = max(le,a[i]);   //每段和最大值最小(分为n组) ri += a[i];            //每段和最大值最大(分为1组) }while(le <= ri){mid = (le + ri)/2;if(check(mid))  ri = mid-1; //v=mid时,组数比m小,那么我们要使组数变大,那么v值就要变小,继续在[l,mid-1]寻找elsele = mid+1;}cout<<le;return 0;
}

洛谷P1182 数列分段 Section II(二分+贪心)相关推荐

  1. 洛谷P1182 数列分段Section II 二分答案

    洛谷P1182 数列分段Section II 二分答案 题意:将 n 个 数 分为 m段 求一种方案,使这m段中最大的和 最小 额..可能有点拗口,其实就是说每一种方案,都有对应的 每段和的最大值, ...

  2. 洛谷P1182 数列分段`Section II`

    . . . . . 分析 首先,分析题目,求最大值的最小化,直接联想到二分 然而关键是要怎么去高效的check 我们考虑一个贪心的思路,能加的就加上,不能则新开一段,所以对于二分的值x,我们从数列a从 ...

  3. 洛谷——P1181 数列分段Section I

    题目描述 对于给定的一个长度为NN的正整数数列A_iAi​,现要将其分成连续的若干段,并且每段和不超过MM(可以等于MM),问最少能将其分成多少段使得满足要求. 输入输出格式 输入格式: 第1行包含两 ...

  4. 二分答案——数列分段 Section II(洛谷 P1182)

    题目选自洛谷P1182 本题解法:二分答案+贪心 思路:首先,分析题目,求最大值的最小化,直接联想到二分,So我们直接二分答案,关键是要怎么去高效的check,我们考虑一个贪心的思路,能加的就加上,不 ...

  5. 数列分段`Section II`(洛谷-P1182)

    题目描述 对于给定的一个长度为N的正整数数列 A−i ,现要将其分成 M(M≤N) 段,并要求每段连续,且每段和的最大值最小. 关于最大值最小: 例如一数列 4 2 4 5 1 要分成 3 段 将其如 ...

  6. 【Luogu1182】数列分段Section II(二分)

    problem 一个长度为N的正整数数列A[i] 将其分成M段,并要求每段连续 求每段和最大值(M段各自的和中最大的那个)最小(某种方案下最小). solution 二分每段和的最大值mid. 如果存 ...

  7. 洛谷P3933 Chtholly Nota Seniorious 【二分 + 贪心 + 矩阵旋转】

    威廉需要调整圣剑的状态,因此他将瑟尼欧尼斯拆分护符,组成了一个nnn行mmm列的矩阵. 每一个护符都有自己的魔力值.现在为了测试圣剑,你需要将这些护符分成 A,B两部分. 要求如下: 圣剑的所有护符, ...

  8. 二分答案二题-P1182数列分段II,P1873砍树

    T1:P1182T1:P1182T1:P1182 数列分段SectionIISectionIISection II 评测记录:https://www.luogu.org/recordnew/lists ...

  9. P1181 数列分段Section I

    传送门:洛谷 P1181 数列分段 AC的代码如下: #include<iostream> #include<cstdio> using namespace std; int ...

最新文章

  1. “AV终结者/8749”病毒清理办法
  2. table control中用帮助(F4)实现自动填充另一字段
  3. 用JavaScript实现动态省市县三级联动
  4. 用数据方法进行简单商品推荐
  5. java第五章抽象类与接口5.1-5.3 2020.3.27+31
  6. java练习_Java基础笔试练习(一)
  7. [导入]LAMP架构下安装Drupal
  8. Python读写CSV格式文件
  9. 102份深圳炒房材料曝光 网友举报千人炒房大会
  10. rm 使用正则表达式 删除文件
  11. 职场奇袭!3分钟完成一天工作
  12. openresty 前端开发入门一
  13. SanDisk U盘加密软件 在其他u盘使用
  14. Vicdas实时历史数据库
  15. 小飞鱼通达二开 通达OA2017集成MongoDB(图文)
  16. 铁路、公路施工企业劳务实名制管理系统解决方案
  17. python期货交易_strategies/python版CTP商品期货交易类库.py at master · gzhou1024/strategies · GitHub...
  18. mscorsvw.exe进程占用CPU资料80%以上的原因
  19. 总有云开日出时候, 万丈阳光照耀你我
  20. Python读取Mysql数据库数据保存至csv文件,以及简单使用Python进行数据分析。(加州房价数据集)

热门文章

  1. python中的namespace
  2. Style后台动态定义[转]
  3. html是超文本标记语言标签,main标签
  4. Unity 接入安卓 支付宝支付SDK遇到ALI38173问题
  5. cept源代码目录结构详解_知识树(转)
  6. CentOS7中编译安装redis5.0
  7. 牛客第三场多校 H Diff-prime Pairs
  8. 在iOS项目中,这样才能完美的修改项目名称
  9. openstack镜像制作详解
  10. Oracle 多行变一列的方法