DP+优先队列--POJ2373

题目描述

稍微难一点的DP,用到了优先队列来简化代码,每个点有几只奶牛用了很巧的方法处理

算法:

递推式子是:f[i+2]=f[i]+1;    ( i+2-2b<=i<=i+2-2a )  f[i]即i点的解

先计算出2a-2b这一段的f[i],然后将节点小于等于i+2-2a处的f[i]值存入优先队列,在计算f[i+2]时,只需要取出优先队列中i不小于i+2-2b的点即可,小于i+2-2b的可以直接舍弃

递归求出其余节点的解,注意加上i处有无奶牛的判断

ac代码:

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

#define maxn 1000000+10
#define inf 1<<31

struct fx{
    int f;int x;
    bool operator < (const fx &a) const{ return f>a.f; }
    fx(int xx=0,int ff=0):x(xx),f(ff){}
};

priority_queue<fx> qfx;

int a,b;
int cowthere[maxn];
int f[maxn];

int main(){
    int n,l,s,e,incow=0;
    memset(cowthere,0,sizeof(cowthere));
    scanf("%d %d %d %d",&n,&l,&a,&b);
    a*=2;b*=2;
    for(int i=0;i<n;i++){
        scanf("%d %d",&s,&e);
        cowthere[s+1]++;
        cowthere[e]--;
    }
    for(int i=0;i<=l;i++){           //得到cowthere 
        f[i]=inf;
        incow+=cowthere[i];
        if(incow>=0)
        cowthere[i]=incow;
    }
    for(int i=a;i<=b;i+=2)
    if(!cowthere[i]){
        f[i]=1;
        if(i<=b+2-a)
        qfx.push(fx(i,1));
    }
    for(int i=b+2;i<=l;i+=2){
        if(!cowthere[i]){
            fx f1;
            while(!qfx.empty()){
                f1 = qfx.top();
                if(f1.x<i-b)
                qfx.pop();
                else
                break;
            }
            if(!qfx.empty())
            f[i]=f1.f+1;
        }
        if(f[i+2-a]!=inf){
            qfx.push(fx(i-a+2,f[i-a+2]));
        }
    }
    if(f[l]==inf)
    cout<<-1<<endl;
    else cout<<f[l]<<endl;
    return 0;
} 
柳暗花明又一村
原文地址:https://www.cnblogs.com/ucandoit/p/8494639.html