POJ 2373 Dividing the Path 单调队列dp

两个队列 p和q

p存储当前所有已经访问过的节点

q对p中的节点进行筛选 选出可以对当前节点进行状态转移的节点,头节点就是最小值,维护这两个队列,时间复杂度就可以降下来

但是不清楚为什么模拟队列的时候永远是h = 1,t = 0

#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 1e6+10;
int q[maxn],head=1,tail;
int p[maxn],h=1,t;
int f[maxn];
bool l[maxn];
int N,L,A,B;
int main()
{
	scanf("%d%d%d%d",&N,&L,&A,&B);
	for(int i = 1,s,e; i <= N; ++i)
	{
		scanf("%d%d",&s,&e);
		for(int j = s+1; j <= e-1; ++j) l[j] = 1;
	}
	memset(f,0x7f,sizeof(f));
	f[0] = 0; p[++t] = 0;
	for(int i = 2; i <= L; i+=2)
	{
		if(l[i]) continue;
		while(h<=t&&(i-p[h])/2>=A)
		{
			while(head<=tail&&f[q[tail]]>=f[p[h]]) tail--;
			q[++tail] = p[h++];
		}
		while(head<=tail && (i-q[head])/2>B) head++;
		if(head <= tail)
		{
			f[i] = f[q[head]]+1;
			p[++t] = i;
		}
	}
	if(f[L]!=0x7f7f7f7f) printf("%d\n",f[L]);
	else printf("-1\n");
	return 0; 
} 

 

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务