最大化最小值 POJ2456 3273

来源:互联网 发布:申请淘宝网店的步骤 编辑:程序博客网 时间:2024/06/05 18:09

POJ2456

最大化最小值

FJ 有一个很长的 barn ,然后里面有 N 棚, N 个棚在一条直线上,第 i 个棚的位置为 xi.
然后他有 c 只羊,为了防止羊相互攻击,则要找出最大的两只羊之间距离,前提是这 c 只羊都必须能放下

确定一个距离s,判断能不能放下这c只羊。
判断的时候使用贪心的方法选择。

int a[100006];//经过排序的bool c(int x)//两头牛之间的距离最短是x可不可以?{    int cnt=1;    int now=a[0];    for(int i=1;i<n;)    {        if(a[i]-now<x){i++;}        else        {            now=a[i];            cnt++;            i++;        }    }    if(cnt<m)        return false;    else        return true;}

POJ3273

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

bool can(int x,int m,int n)//贪心的选择{    int sum=0;    int cnt=0;    for(int i=1;i<=n;i++)    {        if(a[i]>x)            return false;        else        {            if(a[i]+sum<=x)                {                   sum=sum+a[i];                   if(i==1){cnt++;}                }            else                {                    sum=a[i];                    cnt++;                }        }    }    if(cnt<=m)return true;    else return false;}

Farmer John is an astounding accounting wizard and has realized he might run out of money to run the farm. He has already calculated and recorded the exact amount of money (1 ≤ moneyi ≤ 10,000) that he will need to spend each day over the next N (1 ≤ N ≤ 100,000) days.
FJ wants to create a budget for a sequential set of exactly M (1 ≤ M ≤ N) fiscal periods called “fajomonths”. Each of these fajomonths contains a set of 1 or more consecutive days. Every day is contained in exactly one fajomonth.
FJ’s goal is to arrange the fajomonths so as to minimize the expenses of the fajomonth with the highest spending and thus determine his monthly spending limit.
Input
Line 1: Two space-separated integers: N and M
Lines 2.. N+1: Line i+1 contains the number of dollars Farmer John spends on the ith day
Output
Line 1: The smallest possible monthly limit Farmer John can afford to live with.
Sample Input
7 5
100
400
300
100
500
101
400
Sample Output
500
Hint
If Farmer John schedules the months so that the first two days are a month, the third and fourth are a month, and the last three are their own months, he spends at most $500 in any month. Any other method of scheduling gives a larger minimum monthly limit.

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

首先明白一点;
这里是最小化最大值
因此can(x)的应该是一个从false逐渐到true的一个过程,找出首先true的那个值就行,也是因为如此,在最后选择左边界或者右边界的时候,我们选择右边界。
然后结合题意如何判断can(x)是true还是false
题目意思是能不能选出连续的k个月(这里假设k=5),让每个月的花费最大值是500,这里根据题意是可以的,但是能不能选择恰好5个月每个月的最大花费是499呢?显然是不行的,为什么呢?
这里又用到了一个贪心的策略:

贪心的选择(也就是做最坏的打算) 不超过x的连续的月,看下,最坏情况下,能够选择连续的几个月,如果最坏的情况下,cnt都大于m,那么这种方案一定不符合题意,

选择例子进行验证:
不妨对样例进行极限考虑,can(100000)一定是对的,因为很显然。
can(499)呢?
贪心的选择 1,2,(3,4),5,(6),(7)当然这里的【5】大于了499显然不符合题意,但是如果忽略这种情况,那么即使是做最坏的打算都不能符合题意,因为一定不能够恰好5个月。

这里仅给出,can的函数

bool c(int x,int m,int n){    int sum=0;    int cnt=0;    for(int i=1;i<=n;i++)    {        if(a[i]>x)            return false;        else        {            if(a[i]+sum<=x)                {                   sum=sum+a[i];                   if(i==1){cnt++;}                }            else                {                    sum=a[i];                    cnt++;                }        }    }    if(cnt<=m)return true;    else return false;//若利用mid值划分的组数比规定的组数要多,则说明mid值偏小,否则偏大,分别对应false,true}
0 0
原创粉丝点击