问题描述:
把一个包含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,不是最小。
算法思路
要解决最大值最小化的问题,基本思路就是选取任意一个范围(输入数组的最大值到数组所有元素的和),然后在这个范围内进行二分法,每次把和范围的中间值mid当作最小值,然后判断在mid值下数组是否能够被分为m个部分
代码如下:
#include <stdio.h>
int n,m;
bool judge(const int *a,int key)
{
int sum=0;
int count=0;
for(int i=0;i<n;i++)
{
sum += a[i];
if(sum>key)
{
sum=a[i];
count++;
}
}
if((count+1)<=m)
return 1;
return 0;
}
void binary(const int *a,int left,int right)
{
while(left<right)
{
int mid=(left+right)/2;;/// left+((right-left)>>1)
if(judge(a,mid))
{
right = mid;
}
else
{
left = mid+1;
}
}
printf("%d\n",left); // ,right %d
}
int main()
{
int t;
int a[505];
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
int left=0;
int right=0;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
right += a[i];
if(a[i]>left)
{
left = a[i];
}
}
binary(a,left,right);
}
return 0;
}