最大值最小化 二分查找

来源:互联网 发布:网络销售总结怎么写 编辑:程序博客网 时间:2024/04/30 07:27
把一个包含n个正整数的序列划分成m个连续的子序列(每个正整数恰好属于一个序列)。设第i个序列的各数之和为S(i),你的任务是让所有S(i)的最大值尽量小。
     例如序列1 2 3 2 5 4 划分成3个序列的最优方案为1 2 3| 2 5| 4,其中S(1)、S(2),S(3)分别为6、7、4最大值为7;
     如果划分成1 2 |3 2| 5 4, 则最大值为9,不如刚才好。n <= 10^6 ,所有数之和不超过10^9。
#include <cstdio>#include <iostream>#include <cmath>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <stack>#include <queue>#include <map>#include <set>#include <tgmath.h>using namespace std;int n,k;int s[20],s1[20];bool calcu(int x){int num = 0;int sum = 0; for(int i = 0;i<n;i++){if(s[i]>x){return false;}if(sum+s[i]>x){s1[i-1] = 1;sum = s[i];num++;if(num > k-1)return false;}else {sum+=s[i];}}return true;}int main(){int num;while(scanf("%d%d",&n,&k)!=EOF){int y = 0;for(int i=0;i<n;i++){scanf("%d",&s[i]);y+=s[i];}int x = 0;while(y>x){memset(s1,0,sizeof(s1));num = x+(y-x)/2;if(calcu(num))y = num;elsex = num+1;}for(int i = 0;i< n;i++){if(s1[i] == 1)printf("%d | ",s[i]);elseprintf("%d ",s[i]);}printf("\n");}}



                                             
0 0
原创粉丝点击