题目大意:有一块长度为l的草原,你需要用洒水器把所有草坪都覆盖并且每块草坪只能被覆盖一次,有n个奶牛所在的草坪属于[l,r],这些区间只能有一个洒水器;
题目解析:定义dp[i]为在第i块草坪结束的时候所苏姚最少的洒水器,dp[i]=min(dp[j]+1),i-2b<=j<=i-2a,还有一个问题就是n个奶牛的问题,其实只要标记那些草坪是不能结束的就可以了;
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn=1010;
const int inf = 0x3fffffff;
struct node
{
int x,y;
}p[maxn];
bool cmp(node a,node b)
{
if(a.x==b.x) return a.y<b.y;
return a.x<b.x;
}
int l,n,a,b,q[1000010],f[1000010];
int main()
{
while(scanf("%d%d",&n,&l)!=EOF)
{
scanf("%d%d",&a,&b);
for(int i=0;i<=l;i++)
f[i]=inf-1;
f[0]=0;
p[0].x=p[0].y=0;
for(int i=1;i<=n;i++)
scanf("%d%d",&p[i].x,&p[i].y);
sort(p+1,p+n+1,cmp);
for(int i=1;i<=n;i++)
for(int j=max(p[i-1].y,p[i].x+1);j<p[i].y;j++) f[j]=inf;
int front=0,rear=0;
for(int i=2*a;i<=l;i+=2)
{
while(front<rear&&q[front]<i-2*b) front++;
while(front<rear&&f[i-2*a]<=f[q[rear-1]]) rear--;
if(f[i-2*a]<inf-1)
q[rear++]=i-2*a;
if(f[i]<inf&&rear>front)
{
f[i]=f[q[front]]+1;
//cout<<i<<" "<<q[front]<<endl;
}
}
//for(int i=1;i<=l;i++) cout<<f[i]<<endl;
if(f[l]<inf-1) printf("%d\n",f[l]);
else printf("-1\n");
}
return 0;
}