博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数列分段
阅读量:7235 次
发布时间:2019-06-29

本文共 1030 字,大约阅读时间需要 3 分钟。

题目描述

对于给定的一个长度为N的正整数数列A[i],现要将其分成M(M≤N)段,并要求每段连续,且每段和的最大值最小。

输入格式

输入文件divide_b.in的第1行包含两个正整数N,M,第2行包含N个空格隔开的非负整数A[i],含义如题目所述。

输出格式

输出文件divide_b.out仅包含一个正整数,即每段和最大值最小为多少。

样例输入

5 3

4 2 4 5 1

样例输出

6

【题目 https://www.luogu.org/problemnew/show/1182】(蒟蒻不会弄链接,望大佬指点orz)

题解

“最大值最小”,二分的标志

二分最大值mid,检查时枚举每个数要放入已有的段还是另起一段,如果一个数放入已有段后,该段和不超过mid,那么放进去,否则另起一段,同时计数器加1.

最后把计数器和M比较,如果不比M大,说明当前mid值足够大,可以小一点,于是r=mid-1;否则说明当前mid值偏小,要大一点,于是l=mid+1。

计数器初始值为1,因为数列至少会被分成一段,(我第一次把计数器初始为0,样例过了,交上去居然全WA了(ㄒ _ ㄒ))

 

#include 
int n,m,a[100005],l,r,mid,ans;bool check(){ int s=1,sum=0; for (int i=1;i<=n;i++) if (sum+a[i]<=mid) sum+=a[i]; else s++,sum=a[i]; return (s<=m); }int main(){ int i; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) { scanf("%d",&a[i]); r+=a[i]; if (a[i]>l) l=a[i]; } while (l<=r) { mid=(l+r)>>1; if (check()) r=mid-1,ans=mid; else l=mid+1; } printf("%d",ans); return 0;}

 

转载于:https://www.cnblogs.com/rabbit1103/p/7786946.html

你可能感兴趣的文章
【LeetCode】144. Binary Tree Preorder Traversal (3 solutions)
查看>>
English Metric Units and Open XML
查看>>
[ES6] 01. Intro to ES6 and traceur compiler
查看>>
专业版Unity技巧分享:使用定制资源配置文件
查看>>
【插件开发】—— 12 GEF入门
查看>>
solr集成mmseg4j分词
查看>>
less语法(一)变量与extend
查看>>
android_launcher的源码详细分析
查看>>
解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)
查看>>
(转)android.intent.action.MAIN与android.intent.category.LAUNCHER
查看>>
分布式消息系统Kafka初步(一) (赞)
查看>>
常见浏览器兼容性问题与解决方式
查看>>
pfsense 2.2RC版本应用
查看>>
图像处理与机器视觉网络资源收罗——倾心大放送
查看>>
超过响应缓冲区限制
查看>>
Fiddler 实现手机的抓包
查看>>
浅谈C++多态性
查看>>
[翻译] GVUserDefaults
查看>>
Openlayer跨域问题解决
查看>>
Windows7下的免费虚拟机(微软官方虚拟机)
查看>>