稍微难一点的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; }