第一个做的二分法,以前一直以为二分法只能用在查找上,没想到二分那么神奇,还可以这样用。
该题的意思是:给你n个数,让你分成m分,要求分得各组的花费之和应该尽可能地小,然后输出花费最大的那组。
解题思路是,不断的二分这n组分成任意分的最大值,具体的还是看代码吧,详细在注释里。
#include <stdio.h>
#define MAX 100005
int n,m;
int check(int mid,int money[])
{
int group=1,i; //份数从1开始
int sum=0;
for(i=1;i<=n;i++)
{
if(sum+money[i]<=mid)
sum+=money[i];
else
{
group++;
sum=money[i];
}
}
if(group>m) //分的组数太多,即mid太小
return 1;
else
return 0;
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
int money[MAX];
int i,low=0,high=0;
for(i=1;i<=n;i++)
{
scanf("%d",&money[i]);
low=low>money[i]?low:money[i]; //当最多分成n份时,下界为所有数的最大值
high+=money[i]; //上界为所有数之和
}
int mid=(low+high)/2;
while(low<high) //不断二分找分成份数最靠近m的mid的最小值
{
if(check(mid,money)) //mid太小 ,即分的组数太多
low=mid+1;
else
high=mid-1;
mid=(low+high)/2;
}
printf("%d\n",mid); //最后得出最合适的值mid
}
return 0;
}