将N个数字分成为K份,每份中元素必须相临,且k份大小相差最近。
例如N=5 K=2
a[]={5,3,1,4,7}; 最优的划分为(5,3,1)和(4,7)
//用m把长度为N的数组a划分为K段或者更小(m值偏大),返回true
//否则返回false(m值偏小)
bool check(int a[],const int k,const int m,int N)
{
int sum=0;int group=1;
for(int i=0;i<N;i++)
{
if(sum+a[i]<=m)
sum+=a[i];
else
{
sum=a[i];
group++;
}
}
if(group<=k)//m偏大
return true;
return false;
}
void BinarySearch()
{
int N;
cin>>N;//输入数组中元素个数
int k;
cin>>k;//输入分段个数
int* a=new int[N];
for(int i=0;i<N;i++)
cin>>a[i];
int left=0,right=0;//right为数组总和 上线
//left为数组中元素最大值,作为下限
for(int i=0;i<N;i++)
{
right+=a[i];//
if(left<a[i])
left=a[i];
}
int mid=left+(right-left)/2;
while(left<right)
{
if(check(a,k,mid,N))//如果mid能够将数组分为k份或者更小,那么mid就偏大了。更新下届
{//mid偏大
right=mid-1;
}
else//mid偏小,更新上界。
left=mid+1;
mid=left+(right-left)/2;
}
cout<<mid<<endl;
int sum=0;
int group=k;
for(int i=0;i<N;i++)
{
if(sum+a[i]<=mid||group==1)
{
cout<<a[i]<<" ";
sum+=a[i];
}
else
{
group--;
cout<<endl;
cout<<"下一组:"<<endl;
cout<<a[i]<<" ";
sum=a[i];
}
}
delete[] a;
}
int _tmain(int argc, _TCHAR* argv[])
{
BinarySearch();
cout<<endl;
return 0;
}