zoukankan      html  css  js  c++  java
  • 【luoguP1182】数列分段 Section II

    题目描述

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

    关于最大值最小:

    例如一数列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,含义如题目所述。

    输出格式

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

    输入输出样例

    输入 #1
    5 3
    4 2 4 5 1
    输出 #1
    6

    说明/提示

    对于20%的数据,有N≤10

    对于40%的数据,有N≤1000

    对于100%的数据,有N≤100000,M≤N, A_iN100000之和不超过10^9

    思路:

      看见这道题,让求每段的最大值最小,显然二分答案,我们二分一个val,左端点为序列的最大值,右端点为序列的和,

      每次二分,如果二分的只满足在限定次数内分成,则r=min-1,否则r=mid+1;

      注意scanf中的括号内不能有空格,否则不输出,还有,

      在使用快读是,读的数与数之间要用分号,不能用逗号,因为C++ 先执行逗号后面的内容,容易出锅。

    代码:

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    int l,r,n,m,a[100100],yilin,sum,mid;
    bool judge(int x)
    {
    	yilin=0,sum=0;
    	for (int i=1;i<=n;i++)
    	{
    		if(sum+a[i]<=x) sum+=a[i];
    		else sum=a[i] , yilin++;
    	}
    	return (yilin >= m);
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%d",&a[i]);
    		r+=a[i];
    		l=max(l , a[i] );
    	}
    	while(l<=r)
    	{
    		 mid=(l+r) / 2;
    		if(judge(mid))l = mid + 1;
    		else r = mid-1;
    	}
    	printf("%d
    ",l);
    	return 0;
    }
    

      

  • 相关阅读:
    计算机方向的一些顶级会议和期刊—Top Conferences and Journals in Computer Science
    jvm dns缓存问题解决方式
    eclipse调试过程中插入代码执行
    Spring Atomikos分布式事务
    spring quartz 注解配置定时任务
    web系统性能分析JavaMelody
    收集到几种开源NLP工具
    记录些实用的linux指令串
    javamelody对Java Application进行监控
    解决ssh连接问题1
  • 原文地址:https://www.cnblogs.com/yelir/p/11535941.html
Copyright © 2011-2022 走看看