贪心-poj 2376-Cleaning Shifts

本文解析了 POJ 2376 题目的解决方案,采用贪心算法安排最少数量的牛以覆盖指定时间段的工作需求。通过排序和选择最优工作区间的策略,实现有效的问题求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

http://poj.org/problem?id=2376

题目意思:

安排n只牛干活,每只牛有固定的工作时间区间片段,问怎样安排使得使用的牛数最少且工作时间能覆盖1~T(给定)。

解题思路:

分析知,很明显的贪心。

先按每头牛的工作开始时间从小到大排序,如果开始时间一样则按结束时间从大到小来排,然后在当前牛工作的时间段内,选择一头牛使它的开始时间在前一头牛的工作时间内,且结束时间最长,然后选择它,反复进行,如果中间没有牛满足条件则直接跳出。

PS:假设当前牛工作时间段是s,e,由于是时间片(时间可以连续a,a+1也是可行的),所以选择下一头牛时,可以在s~e+1范围内选。

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<sstream>
#include<cstdlib>
#include<string>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<list>
#include<queue>
#include<ctime>
#include<bitset>
#define eps 1e-6
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define ll __int64
#define LL long long
#define lson l,m,(rt<<1)
#define rson m+1,r,(rt<<1)|1
#define M 1000000007
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define Maxn 26000
int n,t;

struct Inf
{
    int s,e;
}inf[Maxn];

bool cmp(struct Inf a,struct Inf b) //先按开始时间从小到大,然后再按结束时间从大到小
{
    if(a.s!=b.s)
        return a.s<b.s;
    return a.e>b.e;
}

int main()
{
   //freopen("in.txt","r",stdin);
   //freopen("out.txt","w",stdout);
   while(~scanf("%d%d",&n,&t))
   {
       bool ans=true;

       for(int i=1;i<=n;i++)
           scanf("%d%d",&inf[i].s,&inf[i].e);
       sort(inf+1,inf+n+1,cmp);
       if(inf[1].s>1)
       {
           printf("-1\n"); //不满足
           continue;
       }
       if(inf[1].e>=t) //只要一个
       {
           printf("1\n");
           continue;
       }
       int la=inf[1].e,ee=inf[1].e,num=1; //第一个的时间

       for(int i=2;i<=n;)
       {
           while(inf[i].s<=(ee+1)&&i<=n) //再保证时间连续的情况下选择结束时间最大的那头牛
           {
               la=max(la,inf[i].e);
               i++;
           }
           if(la>ee) //更新当前牛
           {
               num++;
               ee=la;
               if(la>=t) //已经达到要求了,不用再选牛了
                   break;
           }
           else //选不出新的牛了 game over
           {
               ans=false;
               break;
           }
       }
       if(la<t) //注意最后的判断情况 wa了好几发
       {
           printf("-1\n");
           continue;
       }
       if(!ans)
            printf("-1\n");
       else
            printf("%d\n",num);


   }
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值