poj 3258 3273

 poj3258 题目  (最大化最小值)(最小值最大化)

题意:牛要到河对岸,在与河岸垂直的一条线上,河中有N块石头,给定河岸宽度L,以及每一块石头离牛所在河岸的距离,现在去掉M块石头,要求去掉M块石头后,剩下的石头之间以及石头与河岸的最小距离的最大值

此题要求最短距离最大,对于最短距离我们知道其范围是1~L,那么可以在该单调区间内进行二分查找不断缩小范围。

那么还需要一个判断函数judge来判断当前距离作为最短距离是否是可行解。如果是可行解,但有可能它不是最优解,那么因为求最大值我们还需要继续向其右部区间查找是否有更优解;如果不是可行解,那么可行解只可能在其左部区间,二分向左部查找。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int Max = 5e4+5;
int L,N,M;
int dis[Max];
/*
要求去掉M块石头后,剩下的石头之
间以及石头与河岸的最小距离的最大值。
*/
int cmp(int a,int b)
{
    return a<b;
}
int Bsearch(int l,int r,int k)
{
    int mid,last,cnt;
    while(l<=r)
    {
        mid=(l+r)>>1;
        last = cnt = 0;
        for(int i=1;i<=N+1;i++)
            if(mid>=dis[i]-dis[last]) cnt++;
            else last  = i;
        if(cnt>k) r = mid-1;
        else l = mid+1;
    }
    return l;
}
int main()
{
    cin>>L>>N>>M;
    dis[0]=0;
    dis[N+1]=L;
    for(int i=1;i<=N;i++)
        cin>>dis[i];
    sort(dis+1,dis+N+1,cmp);
    int ans = Bsearch(0,L,M);
    cout<<ans<<endl;
   return 0;
}

poj 3273 题目(最小化最大值)(最大值最小化)

#include<stdio.h>
#include<iostream>
#include <algorithm>
#include<math.h>
using namespace std;
const int Max_N=1e5+5;
const int INF = 0x3f3f3f3f;
int N,M;
int day[Max_N];

 bool C(int mon)
{
    int sum=0,cnt=0;
    for(int i=0;i<N;i++)
    {
        if(day[i]>mon) return false;
        if(sum+day[i]<=mon) sum+=day[i];
        else {
            sum=day[i];
            cnt++;
        }
    }
    cnt++;
    return cnt<=M;
}

void solve()
{
    int l=0,r=INF;
    while(r-l>1)
    {
        int mid = (r+l) >> 1;
        if(C(mid)) r= mid;
        else l = mid;
    }
    printf("%d
",r);
}
int main()
{
    scanf("%d%d",&N,&M);
    for(int i=0;i<N;i++)
    scanf("%d",&day[i]);
    solve();

    return 0;
}
原文地址:https://www.cnblogs.com/qie-wei/p/10160142.html