这道题和poj3273 刚好是两个相反的例子,一个是求最大值最小,这个是求最小值最大。
就是把一串数分成若干组,使得 组和(该组所有数的和)最大的哪一组的值最大或者最小。
应用二分的思想,在距离最小值和总和之间二分查找。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 51111
using namespace std;
int a[MAX],d[MAX];
int L,N,M;
int sum,ans,l,r,cnt,mid;
int work(int m) //检验mid值是否满足划分要求
{
int i,j;
sum=0;cnt=0;
for(i=1;i<=N+1;i++)
{
sum+=d[i];
if(sum<=m)
cnt++;
else sum=0;
}
return cnt;
}
int main()
{
int i,j;
scanf("%d%d%d",&L,&N,&M);
for(i=1;i<=N;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+N+1);
l=L;r=L;
for(i=1;i<=N;i++)
{
d[i]=a[i]-a[i-1];
if(l>d[i]) l=d[i];
}
d[i]=L-a[N];
if(l>d[i]) l=d[i];
while(l<r) //二分
{
mid=(l+r)/2;
int temp=work(mid);
if(temp<=M) //如果可以移除的块数小于等于M,说明mid值还可以更大一些。
l=mid+1;
else {
r=mid; //反之,mid应该小一点。
}
}
printf("%d\n",l);
return 0;
}