首页 > 其他分享 >数列分段(二分)

数列分段(二分)

时间:2024-11-13 14:20:59浏览次数:1  
标签:二分 数列 int 最大值 mid leq 分段

[数列分段 Section II]

题目描述

对于给定的一个长度为 \(N\) 的正整数数列 \(A_{1\sim N}\),现要将其分成 \(M\)(\(M\leq 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

提示

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

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

对于 \(100\%\) 的数据,\(1\leq N\leq 10^5\),\(M\leq N\),\(A_i < 10^8\), 答案不超过 \(10^9\)。

#include <bits/stdc++.h>
using namespace std;

int main() 
{
    int n, m;
    scanf("%d%d", &n, &m);

    vector<int> a(n);
    int l = 0, r = 0;

    for (int i = 0; i < n; i++) //for (int i = 1; i <= n; i++),会导致数组越界应该从 i = 0 开始遍历(会错过第一个元素 a[0],并且在 i = n 时会访问到 a[n],这会导致数组越界RE)
    {
        scanf("%d", &a[i]);
        l = max(l, a[i]);//更新l为数组中的最大值,r为数组所有元素的和
        r += a[i];
    }

    while (l < r)
    {
        int mid = l + (r - l) / 2;
        int sum = 0, baka = 1; //最后一段也需要计数

        for (int i = 0; i < n; i++) 
        {
            if (sum + a[i] > mid) 
            {
                sum = a[i];
                baka++;
            } else {
                sum += a[i];
            }
        }

        if (baka > m)
        {
            l = mid + 1; // 分段多,说明mid太小,增大l
        } else {
            r = mid;  //段数少,说明数太大,要改小一点
        }
    }

    printf("%d\n", l);

    return 0;
}

模板:

最大值最小(本题)

while(l<r)
{
    int mid=(l+r)>>1;
    if(check(mid))
        r=mid;
    else
        l=mid+1;
}

最小值最大

while(l<r)
{
    int mid=(l+r+1)>>1;
    if(check(mid))
        l=mid;
    else
        r=mid-1;
}

标签:二分,数列,int,最大值,mid,leq,分段
From: https://www.cnblogs.com/gailixia/p/18543832

相关文章

  • 使用 PowerShell 创建多个 .reg 文件进行分段(切片)并且能够在执行时按顺序合并并执行,我
    使用PowerShell创建多个.reg文件进行分段(切片)并且能够在执行时按顺序合并并执行,我们可以按照以下步骤进行:目标:将一个大的 .reg 文件分割成多个小文件。每个小文件(分段)都将是一个有效的 .reg 文件,可以独立执行。使用PowerShell自动生成这些分段 .reg 文件,并执行它......
  • 整数二分—建造水族馆
    建造水族馆每次测试时限:2秒每次测试的内存限制:256兆字节输入:标准输入输出:标准输出题目:你喜欢养鱼,所以你决定建造一个水族馆。你有一块由n根柱子组成的珊瑚,其中i根柱子高ai个单位。之后,你将在珊瑚周围建造一个水族箱,具体如下:选取一个整数h>=1--水箱的高度。在水箱两侧建......
  • Python程序:计算特定数列之和
    题目要求编写一个Python程序,计算数列$s=a+aa+aaa+aaaa+\ldots$的和,其中$a$是一个数字,数列中每个数都是由$a$重复组成,且重复次数逐渐增加。用户可以通过键盘控制数列中相加的数的个数。解题思路为了计算这个数列的和,我们需要首先理解数列的构成。每个数都......
  • 整数二分
    洛谷p1873砍树题目描述:伐木工人Mirko需要砍M米长的木材。对Mirko来说这是很简单的工作,因为他有一个漂亮的新伐木机,可以如野火一般砍伐森林。不过,Mirko只被允许砍伐一排树。Mirko的伐木机工作流程如下:Mirko设置一个高度参数H(米),伐木机升起一个巨大的锯片到高度H,并锯掉......
  • 在C语言中用函数求fibonacci(斐波那契)数列前n项的和
    1.功能用函数求fibonacci数列前n项的和。2.说明fibonacci数列为数列的第一项值为1,第二项值也为1,从第三项开始,每一项均为其前面相邻两项的和。3.题目例如:当n=28时,运行结果:832039。请编写sum函数。#include<stdio.h>//函数sum用于计算斐波那契数列前n项的和longsum......
  • 【算法】【优选算法】二分查找算法(上)
    目录一、二分查找简介1.1朴素二分模板1.2查找区间左端点模版1.3查找区间右端点模版二、leetcode704.⼆分查找2.1二分查找2.2暴力枚举三、Leetcode34.在排序数组中查找元素的第⼀个和最后⼀个位置3.1二分查找3.2暴力枚举四、35.搜索插⼊位置4.1二分查找4.2......
  • 二分法查找
    二分查找/*折半查找,二分查找*///已经排好序的数组中进行查询#include<stdio.h>intmain(){ intlow,high,mid,userInput;//highlowmid记录的是数组下标 intflag=0;//记录能否找到 inta[10]={12,14,21,35,48,57,69,78,89,99};//二分查找的前提:已经有序 low=0......
  • 二分答案模板
    本篇主要介绍二分答案的几个模板1.常用二分模板整数二分模板1将区间划分为[l,mid]和[mid+1,r]则对应的边界更新操作为r=mid,和l=mid+1;中点mid不要+1(相当于向下取整);//整数二分模板1intbsearch_1(intl,intr){while(l<r){......
  • 知识点扫盲:二分答案
    本条博客以及本系列用于记录算法学习中不熟悉或少见的知识点一.关于二分答案的来源和应用由于本大一==蒟蒻==没有经过系统性的学习,在一场牛客小白月赛中首次听说二分答案这一操作,十分震惊其效率与作用,遂写此篇来记录关于二分答案有关的概念[二分法]"https://oi-wiki.or......
  • ABC372D ABC379F 题解 单调栈二分
    ABC372DABC379F题解单调栈二分一直觉得AT上面学到的东西比CF要多一些,无意捧一踩一,但可能是我太菜的原因,毕竟ABC的题目普遍要比Div.2简单一些。好多次碰到这个单调栈里面二分的trick了,所以写一篇来总结一下。ABC372D形象地给定一系列Buildings的高度\(h\),保证每个......