POJ-2373-单调队列优化dp

题目大意:有一块长度为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;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值