洛谷P1182 数列分段Section II 二分答案
Posted third2333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1182 数列分段Section II 二分答案相关的知识,希望对你有一定的参考价值。
洛谷P1182 数列分段Section II
二分答案
题意:将 n 个 数 分为 m段 求一种方案,使这m段中最大的和 最小
额。。可能有点拗口,其实就是说每一种方案,都有对应的 每段和的最大值,
要求一种方案,使最大值最小
题解 :二分答案 mid为分成的最大值,
然后O(n) 判断 答案 是否可行
贪心的做下去,如果再加上就要超过了,那就新开一段
最后判断开的段数是否小于 m
1、注意要判断 如果当前这个值大于 mid,一个值就已经大于 mid了,那就直接退出
了,否则 ,这个值也只会单独算为一段的,其实他一段都放不下
2、或者还有之中方法 答案从 最大的 a[ i ] 开始枚举。。。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <cmath> 5 #include <string> 6 #include <algorithm> 7 #include <iomanip> 8 #include <iostream> 9 using namespace std ; 10 11 const int maxn = 100011 ; 12 int n,m,l,r,mid ; 13 int a[maxn] ; 14 15 inline bool check( int mid ) 16 { 17 int ans = 0,sum = 0 ; 18 for(int i=1;i<=n;i++) 19 { 20 if(a[ i ]>mid) return 0 ; 21 // 1、注意要判断 如果当前这个值大于 mid,一个值就已经大于 mid了, 22 //那就直接退出了,否则 ,这个值也只会单独算为一段的,其实他一段都放不下 23 if( sum+a[ i ] > mid ) 24 ans++,sum = 0 ; 25 sum+=a[ i ] ; 26 } 27 ans++ ; 28 return ans <= m ; 29 } 30 31 int main() 32 { 33 scanf("%d%d",&n,&m) ; 34 for(int i=1;i<=n;i++) scanf("%d",&a[ i ]) ; 35 l = 0,r = 1e9 ; 36 while( l<r ) 37 { 38 mid = ( l+r )>>1 ; 39 if(check(mid)) 40 r = mid ; 41 else 42 l = mid + 1 ; 43 } 44 printf("%d\n",r) ; 45 return 0 ; 46 }
以上是关于洛谷P1182 数列分段Section II 二分答案的主要内容,如果未能解决你的问题,请参考以下文章