zoukankan      html  css  js  c++  java
  • POJ:2456 Aggressive cows(z最大化最小值)

    描述

    农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000).
    但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗。为了不让牛互相伤害。John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢?

     
    输入
    第一行:空格分隔的两个整数N和C
    第二行——第N+1行:分别指出了xi的位置
    输出
    每组测试数据输出一个整数,满足题意的最大的最小值,注意换行。
    样例输入
    5 3
    1
    2
    8
    4
    9
    样例输出
    3

    意要表达的是:把C头牛放到N个带有编号的隔间里,使得任意两头牛所在的隔间编号的最小差值最大。

    分析:这是一个最小值最大化的问题。先对隔间编号从小到大排序,则最大距离不会超过两端的两头牛之间的差值,最小值为0。所以我们可以通过二分枚举最小值来求。假设当前的最小值为x,如果判断出最小差值为x时可以放下C头牛,说明当前的x有点小,就先让x变大再判断;如果放不下,说明当前的x太大了,就先让x变小然后再进行判断。直到求出一个最大的x就是最终的答案。

    现在来搞下解题步骤:

    C(d)=可以安排牛的位置使得最近的两头牛的距离都不小于d

    那么现在问题就变成求满足C(d) 的最大d,另外最近的间距不小于d也可以说成是所有牛的间距不小于d;

    在问题上的判断使用贪心法便可以非常容易地求解。

    1.对牛舍的位置x进行排序

    2.把第一头牛放入x0的牛舍

    3.如果第i头牛放入了xj的话,第i+1头牛就要放入满足xj+d<=xk 的最小的xk中

    AC 代码:

    #include<stdio.h>
    #include<algorithm>
    #define MAX 101000
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m;
    int a[MAX];
    bool C(int d)
    {
        int last=0;
        for(int i = 1 ; i < m ; i++)
        {
            int crt=last+1;
            while(crt<n&&a[crt]-a[last]<d)///只需要比较k-1次找出最适合的值d来搞k头牛,用last&crt来表示上一头牛和当前牛的位置
                crt++;
            if(crt==n)
                return false;///到达最大值n。说明d的值小了
            last = crt;
        }
        return true;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i = 0 ; i < n ; i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        int st = 0,en=INF,mid;
        while(en-st>1)
        {
             mid=(en+st)/2;
            if(C(mid)==false)
                en=mid;
            else
                st=mid;
        }
        printf("%d
    ",(en+st)/2);///个人突杨想到的问题,因为我不知道是en还是st
    }
    View Code

    另一种解法:

    #include<stdio.h>
    #include<algorithm>
    #define MAX 101000
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m;
    int a[MAX];
    bool C(int d)
    {
        int sum=0;
        int ans=1;
        for(int i=1;i<n;i++)
        {
            if((sum+a[i]-a[i-1])<d)
            {
                sum+=a[i]-a[i-1];
    
            }
            else
            {
                sum=0;
                ans++;
            }
        }
        if(ans>=m)
            return true;
        return false;
    }
    int main()
    {
        int en=-1,st=INF;
        scanf("%d%d",&n,&m);
        for(int i = 0 ; i < n ; i++)
        {
            scanf("%d",&a[i]);
        }
    
        sort(a,a+n);
        en=a[n-1]-a[0];
        for(int i=1;i<n;i++)
        {
            st=min(st,a[i]-a[i-1]);
    
        }
         while(en-st>1)
         {
             int mid=(en+st)/2;
              if(C(mid))
                st=mid;
              else
                en=mid;
         }
        printf("%d
    ",(st+en)/2);///个人突杨想到的问题,因为我不知道是en还是st
    }
    View Code
  • 相关阅读:
    jQuery初级篇
    DOM初级篇
    CSS基础篇
    javascript 初级篇
    HTML 基础篇
    Oracle文章中常用数据表的描述
    Oracle视图基础
    Oracle序列简单应用
    Oracle关联查询关于left/right join的那点事
    赋值和算术运算符
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/8921662.html
Copyright © 2011-2022 走看看