目录
Monthly Expense(POJ3273)最小化最大值
Aggressive cows(POJ2456)最大化最小值
题意(POJ3273)
给出农夫在n天中每天的花费,要求把这n天分作m组,每组的天数必然是连续的,要求分得各组的花费之和应该尽可能地小,最后输出各组花费之和中的最大值.
思路
1.二分的内容,花费最大一组的值
2.二分的范围,初始应该大于等于数组的最大值,初始等于所有花费和。
3.check函数,假设花费最大一组的值等于x,则可以分为几组,返回组数
4.如果组数小于等于m,说明x假设大了,为使最大值最小化,缩小区间移动r。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<limits.h>
using namespace std;
const int N=1e5+10;
int a[N];
int n,m;
int check(int x)
{
int sum=0,cnt=1;
for(int i=1;i<=n;i++)
{
sum+=a[i];
if(sum<x)
{
continue;
}
else if(sum==x)
{
cnt++;
sum=0;
}
else
{
cnt++;
sum=a[i];
}
}
return cnt;
}
int main()
{
cin>>n>>m;
int maxx=INT_MIN;
int sum=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
maxx=max(maxx,a[i]);
sum+=a[i];
}
int l=maxx,r=sum,mid;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid)<=m)
{
r=mid-1;
}
else
{
l=mid+1;
}
}
cout<<l<<endl;
}
题意(POJ2456)
有n个牛栏,选m个放进牛,相当于一条线段上有 n 个点,选取 m 个点,
使得相邻点之间的最小距离值最大
思路
1.二分的内容,相邻点之间的最小距离
2.二分的范围,初始:
3.check函数,二分枚举相邻两牛的间距,判断大于等于此间距下能否放进所有的牛。
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<limits.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1e6+10;
int a[N];
int n,m;
bool check(int x)
{
int cnt=a[1],num=1;
for(int i=2;i<=n;i++)
{
if(a[i]-cnt>=x)
{
num++;
cnt=a[i];
}
if(num>=m)
return true;
}
return false;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+1+n);
int r=a[n]-a[1],mid,l=INT_MAX;
for(int i=2;i<=n;i++)
{
l=min(l,a[i]-a[i-1]);
}
while(l<r)
{
mid=l+r+1>>1;
if(check(mid))
{
l=mid;
}
else
{
r=mid-1;
}
}
printf("%d\n",r);
}