您的位置:首页 > 其它

POJ 3273 Monthly Expense 二分查找的应用

2016-02-24 00:06 232 查看
点击打开链接

题意

给出农夫在n天中每天的花费,要求把这n天分作m组,每组的天数必然是连续的,要求分得各组的花费之和应该尽可能地小,最后输出各组花费之和中的最大值

思路:

1 普通枚举(超时)

先把N个值中的最大值Max作为作为分组的最小和,然后暴力分组看看分的组数是不是小于m

如果小于m就找到了

如果不小于 就让Max++;一直枚举到满足条件的值为止

2 二分 枚举不是Max++进行了 ,而是先确定一个最大和与最小和

然后二分判断边界

二分的条件知道上下边界即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
int a[100010];
int n,m;
int judge(int low,int high)
{
if(low>=high)
return low;
int sum,num,mid;
int zmax=high;
while(low<=high)   ///勿漏 =
{
mid=(low+high)/2;
sum=0;
num=1;
for(int i=0; i<n; i++)
{
if(sum+a[i]<=mid)
sum+=a[i];
else
{
sum=a[i];
num++;
}
if(num>m)
break;
}
if(num>m)
low=mid+1;
else    ///满足分组条件
{
high=mid-1;
zmax=min(zmax,mid);    ///确定满足分组条件的最小值
}
}
return zmax;
}
int main()
{
//    freopen("stdd.txt","r+",stdin);
//    freopen("std.txt","w+",stdout);
while(~scanf("%d%d",&n,&m))
{
int low=-1,high=0;
for(int i=0; i<n; i++)
{
scanf("%d",&a[i]);
high+=a[i];
low=max(a[i],low);
}
printf("%d\n",judge(low,high));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: