DP灌溉草场

166 篇文章 0 订阅

题目 :poj2373

代码:

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int INFINITE = 1<<30;
const int MAXL = 1000010;
const int MAXN = 1010; 
int F[MAXL]; 
int cowThere[MAXL];
int N,L,A,B; 
struct Fx {
	int x; 
	int f;
	bool operator<(const Fx & a) const { 
		return f > a.f; 
	}
	Fx(int xx=0,int ff=0):x(xx),f(ff) { }
};// 在优先队列里,f值越小的越优先
priority_queue<Fx> qFx;
int main() 
{
	cin >> N >> L;
	cin >> A >> B;
	A <<= 1; 
	B <<= 1; //A,B的定义变为覆盖的直径(半径乘于2) 
	memset(cowThere,0,sizeof(cowThere));
	for( int i = 0;i < N; ++i ) {
		int s,e;
		cin >> s >> e;
		++cowThere[s+1]; //从s+1起进入一个奶牛区
		--cowThere[e]; //从e起退出一个奶牛区
	}
	int inCows = 0; //表示当前点位于多少头奶牛的活动范围之内
	for( int i = 0;i <= L ; i ++) { //算出每个点是否有奶牛
		F[i] = INFINITE;
		inCows += cowThere[i];
		cowThere[i] = inCows > 0;//...妙啊!!! 
	}//初始化数组 

	for( int i = A;i <= B ; i += 2 ) //初始化队列(一倍小直径和一倍大直径之间 
		if(! cowThere[i] ) { 
			F[i] = 1;
			if( i <= B + 2 - A ) //这句话的意思是  对B+2这个 dp起始点  把所有能影响这个点的坐标入队 
				qFx.push(Fx(i,1)); 
		}
	for( int i = B + 2 ; i <= L; i += 2 ) {
		if( !cowThere[i] ) { //如果这里没有奶牛(即水龙头边界可以是这个坐标) 
			Fx fx;
			while(!qFx.empty()) {//删除不能影响到当前点的队头 
				fx = qFx.top();
				if( fx.x < i - B )
					qFx.pop();
				else
					break;
			}
			if ( ! qFx.empty() ) //当前点为对头加 1,
				F[i] = fx.f + 1;
		}
		if( F[i + 2 - A] != INFINITE) {//入队一个能影响到下一个点的元素 
			qFx.push(Fx(i + 2 - A, F[i + 2 - A])); 
		} 
	}//dp全过程 一旦出现某个点不能被浇灌到 那么就会断层; 
	if( F[L] == INFINITE ) //如果不满足条件 
		cout << -1 <<endl;
	else 
		cout << F[L] << endl; //满足条件 
	return 0;
} // 复杂度:O(nlogn)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值