1.4.4 数列分段(题解:二分)

举报
irrational 发表于 2022/01/18 01:37:59 2022/01/18
【摘要】 我们同样以一个题目继续讲解二分的应用。 1.4.4 数列分段 Description 对于给定的一个长度为N的正整数数列A[1..N]A[1..N]A[1..N],现要将其分成MMM(M≤NM≤NM≤N)段,并要求每段连续,且每段和的最大值最小。 关于最大值最小: 例如一数列4 2 4 5 1要分成3...

我们同样以一个题目继续讲解二分的应用。

1.4.4 数列分段

Description

对于给定的一个长度为N的正整数数列A[1..N]A[1..N]A[1..N],现要将其分成MMM(M≤NM≤NM≤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。

Input

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

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

Output

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

Sample Input 1

5 3
4 2 4 5 1

Sample Output 1

6

Hint

对于 100% 的数据,1≤ N≤ 100,000,M≤N,A[i]≤ 1081 \le  N \le  100,000, M≤N,A[i] \le  10^8 1≤ N≤ 100,000,M≤N,A[i]≤ 108

答案不超过10910^9109


  
  1. #include <cstdio>
  2. #include <algorithm>
  3. int n, m;
  4. int l, r, mid, ans;
  5. int a[100010];
  6. //二分答案,枚举出一个最大值,根据分组情况调整最大值,求出最优最大值。
  7. /*
  8. * check 函数
  9. * 作用:
  10. * 根据枚举出的最大值,来分组,根据分出的组数来调整最大值
  11. * 变量:
  12. * x : 枚举出的最大值
  13. * sum : 分组时每组的和
  14. * count : 分出的组数
  15. */
  16. bool check(int x)
  17. {
  18. int sum=0, count=0;//t2: 组数 t1: 每组的和
  19. for(int i=0; i<n; i++){
  20. if(sum+a[i]<=x)sum+=a[i]; //如果还是小于mid,就继续加上去
  21. else //objective 1如果当前sum已经达到当前最大值应该怎么处理?
  22. {
  23. sum=a[i]; //设置sum为当前数字,相当于换入下一组
  24. count++;
  25. }
  26. }
  27. if(count>=m)return true;//objective 2
  28. return false;
  29. }
  30. int main()
  31. {
  32. scanf("%d %d", &n, &m);
  33. for(int i=0; i<n; i++){
  34. scanf("%d", &a[i]);
  35. r += a[i];
  36. l = std::max(l, a[i]);
  37. }
  38. while( l<=r ){
  39. mid=(l+r)/2;
  40. if( check(mid) )l=mid+1;//如果最后的count是大于m的话,说明mid太小了,需要l往右移
  41. else {//否则就是mid太大了
  42. r=mid-1;
  43. }
  44. }
  45. printf("%d",l);
  46. return 0;
  47. }

显而易见,二分法给这种看似难以解决的最大最小问题提供了方法,利用二分枚举,降低了思维难度。

文章来源: blog.csdn.net,作者:irrationality,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/weixin_54227557/article/details/120581055

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。