首页 > 代码库 > 洛谷P1182 数列分段Section II 二分答案
洛谷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 二分答案
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。