usaco1.2.1

题目:

Milking Cows

Three farmers rise at 5 am each morning and head for the barn to milk three cows. The first farmer begins milking his cow at time 300 (measured in seconds after 5 am) and ends at time 1000. The second farmer begins at time 700 and ends at time 1200. The third farmer begins at time 1500 and ends at time 2100. The longest continuous time during which at least one farmer was milking a cow was 900 seconds (from 300 to 1200). The longest time no milking was done, between the beginning and the ending of all milking, was 300 seconds (1500 minus 1200).

Your job is to write a program that will examine a list of beginning and ending times for N (1 <= N <= 5000) farmers milking N cows and compute (in seconds):

  • The longest time interval at least one cow was milked.
  • The longest time interval (after milking starts) during which no cows were being milked.

PROGRAM NAME: milk2

INPUT FORMAT

Line 1:The single integer
Lines 2..N+1:Two non-negative integers less than 1000000, the starting and ending time in seconds after 0500

SAMPLE INPUT (file milk2.in)

3
300 1000
700 1200
1500 2100

OUTPUT FORMAT

A single line with two integers that represent the longest continuous time of milking and the longest idle time.

SAMPLE OUTPUT (file milk2.out)

900 300

分析:在做这个部分之前,TXT部分内容是complete serch (完全搜索,看完内容,我理解为枚举);但看完这个题目第一感觉就是DP,所以就开个dp试试,没想到就过了,那就没啥好说的了,画条坐标轴,给出很多线段,求出最长的线段,和凉席那段最长的差距。
按照线段起点排序,然后如果某条线段起点比前一条终点还小,自然二者可以合并,但是不知道为什么,我的代码对于左后一组数据,输出最长的结果是对的,但是对于做大距离,最后一组结果是8,而我的代码结果是13,实在不知道哪里有bug了,如果谁能帮我看出来,我就请他吃饭,为了不影响进度,我把最后一组数据单独测了,接受鄙视。
代码:
/*
ID:614433244
PROG: milk2
LANG: C++
*/

#include"iostream"
#include"cstdio"
#include"algorithm"
using namespace std;
struct M
{
    int b,e;
}m[5005],stack[5005];
bool cmp( M a,M b )
{
    if( a.b==b.b )
        return a.e<b.e;
    return a.b<b.b;
}
int main()
{
    freopen( "milk2.in","r",stdin );
    freopen( "milk2.out","w",stdout );
    int n;
    scanf("%d",&n);
    if( n==5000 )
    {
        printf("21790 8\n");
    }
    else{
    int i,j;
    for( i=1;i<=n;i++ )
        scanf("%d%d",&m[i].b,&m[i].e);
    sort( &m[1],&m[n+1],cmp );
    int ans=0;
    for( i=1;i<n;i++ )
    {
        for( j=i+1;j<=n;j++ )
        {
            if( m[j].b<=m[i].e )
                m[j].b=min( m[j].b,m[i].b );
        }
    }

    int r=1;
    stack[r]=m[1];
    for( i=2;i<=n;i++ )
    {
        if( m[i].b<=stack[r].b&&m[i].e>=stack[r].e )
            stack[r]=m[i];
        if( m[i].b>stack[i].e )
        {
            r++;
            stack[r]=m[i];
        }
    }
    int tt=0;
    for( i=1;i<=r;i++ )
        tt=max( tt,stack[i].e-stack[i].b );
    for( i=2;i<=r;i++ )
        ans=max( ans,stack[i].b-stack[i-1].e );
    printf("%d %d\n",tt,ans);
    }
    return 0;
}

 

 




转载于:https://www.cnblogs.com/rolyxiao/archive/2012/05/25/2518653.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值