清理班次

农民约翰正在指挥他的N头牛进行清理工作。
他将一天划分为了T个班次(1~T)。
每头牛都只能在一天中的某一个时间段内进行不间断的工作。
你需要帮助约翰排列出一个合理的奶牛的清理班次,使得每个班次都有奶牛在进行清理,而且动用的奶牛数量可以尽可能的少。

输入格式
第1行:两个空格隔开的整数N和T。
第2…N+1行:第i+1行包含两个整数,分别表示第i头牛可以进行工作的开始时间和结束时间。

输出格式
输出一个整数,表示在每个班次都有奶牛清理的情况下,所需的奶牛最小数量。如果无法做到每个班次都有奶牛清理,则输出-1。

数据范围
1≤N≤25000,
1≤T≤106
输入样例:
3 10
1 7
3 6
6 10
输出样例:
2
题目链接

思路:
1、贪心(比较简单)
2、dp, dp[i]:从1~ i最少需要多少头奶牛。先将每头牛的时间段按右端点从小到大进行排序,依次扫描每条线段(L~R) dp[R]=min(dp[R],min(dp[k])+1) (L-1<=k<=R-1),由于数据范围比较大,所以可以用线段树进行区间的最小值查找和更新。

具体实现:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=25010,M=1e6+10,INF=1e8;

struct node
{
    int l,r;
    bool operator <(node &t)
    {
        return r<t.r;
    }
}row[N];//每一头奶牛工作时间段

struct node1
{
    int l,r,v;
}tr[4*M];//线段树结点的表示范围和该范围内的最小值

int n,m;

void build(int u,int l,int r)
{
    tr[u]={l,r,INF};//初始化为无穷大
    if(l==r)return ;
    int mid=l+r>>1;
    build(u<<1,l,mid);
    build(u<<1|1,mid+1,r);
}

void update(int u,int k,int v)//u表示结点,k表示要更新的dp[r],v:更新的值
{
    if(tr[u].l==tr[u].r)
    {
        tr[u].v=min(tr[u].v,v);
        return;
    }
    int mid=tr[u].l+tr[u].r>>1;
    if(k<=mid)update(u<<1,k,v);
    else  update(u<<1|1,k,v);
    tr[u].v=min(tr[u<<1].v,tr[u<<1|1].v);
}

int query(int u,int l,int r)
{
    if(tr[u].l>=l&&tr[u].r<=r)
        return tr[u].v;
    int mid=tr[u].l+tr[u].r>>1;
    int res=INF;
    if(l<=mid) res=query(u<<1,l,r);
    if(r>mid) res=min(res,query(u<<1|1,l,r));
    return res;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)scanf("%d%d",&row[i].l,&row[i].r);
    sort(row,row+n);
    build(1,0,m);
    update(1,0,0);
    for(int i=0;i<n;i++)
    {
        int l=row[i].l,r=row[i].r;
        int v=query(1,l-1,r-1)+1;
        update(1,r,v);
    }
    int res=query(1,m,m);
    if(res==INF)
        res=-1;
    printf("%d\n",res);
    return 0;
}

扩展:
农夫约翰雇佣他的N头奶牛帮他进行牛棚的清理工作。他将全天分为了很多个班次,其中第M个班次到第E个班次(包括这两个班次)之间必须都有牛进行清理。这N头牛中,第 i 头牛可以从第ai个班次工作到第bi个班次,同时,它会索取ci的佣金。请你安排一个合理的清理班次,使得[M,E]时间段内都有奶牛在清理,并且所需支付给奶牛的报酬最少。
输入格式
第1行:包含三个整数N,M和E。第2…N+1行:第i+1行包含三个整数ai,bi,ci。
输出格式
输出一个整数,表示所需的最少佣金。如果无法做到在要求时间段内都有奶牛清理,则输出-1。

该题就能很好的使用以上代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值