POJ 2373 Dividing the Path(队列dp)

这题的模型是给予2A~2B间隔为2的板子,用最少的板子覆盖线段L。

那么设f(x)代表覆盖线段x最少用的板子,那么结果就是f(L)了。

当x为奇数时,f[x]=inf;

当x有奶牛时,发[x]=inf;

当x<2A时,f[x]为inf。

那么当x大于等于2A小于等于2B,f为1。

从i=2B+2开始,就要开始dp了。从i-2B到i-2A从选一个最小的加一,知道i为L。

如果选择遍历,那肯定会超时,所以用优先队列,取队头,合适就咬,不合适就继续取,当时不能把大于i-2A的放入,因为之后还要用,所以不能丢,但不丢又不能取下一个,所以会导致dp无法进行。

//
//  main.cpp
//  Richard
//
//  Created by 邵金杰 on 16/9/7.
//  Copyright © 2016年 邵金杰. All rights reserved.
//



#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
struct Fx{
    int f,p;
    Fx(int f=0,int p=0): f(f),p(p) {}
    bool operator < (const Fx &e) const {
        return f>e.f;
    }
};
const int inf=99999999;
const int maxn=1000000+100;
int Cowthere[maxn],f[maxn];
int main()
{
    memset(f,0,sizeof(f));
    memset(Cowthere,0,sizeof(Cowthere));
    int n,l;
    int a,b;
    int s,e;
    cin>>n>>l;
    cin>>a>>b;
    a<<=1;b<<=1;
    for(int i=0;i<n;i++)
    {
        cin>>s>>e;
        Cowthere[s+1]++;
        Cowthere[e]--;
    }
    int nowCow=0;
    for(int i=0;i<=l;i++)
    {
        f[i]=inf;
        nowCow+=Cowthere[i];
        Cowthere[i]=nowCow>0;
    }
    priority_queue<Fx> pq;
    for(int i=a;i<=b;i+=2)
    {
        if(!Cowthere[i]){
            f[i]=1;
            if(i<=b+2-a) pq.push(Fx(1,i));
        }
    }
    for(int i=b+2;i<=l;i+=2)
    {
        if(!Cowthere[i])
        {
            Fx ff;
            while(!pq.empty())
            {
                ff=pq.top();
                if(ff.p<i-b) pq.pop();
                else break;
            }
            if(!pq.empty())
                f[i]=ff.f+1;
        }
        if(f[i-a+2]!=inf)
            pq.push(Fx(f[i-a+2],i-a+2));
    }
    if(f[l]==inf)
        cout<<-1<<endl;
    else
        cout<<f[l]<<endl;
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值