出行(动态规划)(单调队列优化)


用优先队列实现的代码:

#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<memory.h>
#include<map>
#include<set>
#include<cmath>
#include<queue>
#define rep(i,a,b) for(register int i=a;i<=b;i++)
#define per(i,a,b) for(register int i=a;i>=b;i--)
using namespace std;
typedef long long LL;
LL l,a,b,t,r;
double p[500005];
int n;
struct node
{
	int p;
	double val;
	inline bool operator<(const node a)const
	{return val>a.val;}
};
priority_queue<node>q1,q2;
bool f1[500005],f2[500005];
double f[500005],ans=1e11;
int main()
{
	freopen("walk.in","r",stdin);
	freopen("walk.out","w",stdout);
	cin>>l>>a>>b>>t>>r;
	cin>>n;
	rep(i,1,n)scanf("%lf",p+i);
	p[++n]=l;
	int p1=1,p2=1;
	rep(i,1,n)
	{
		f1[i-1]=1;
		q1.push((node){i-1,(p[i]-p[i-1])/a+f[i-1]-p[i]/a});
		while(p1<i&&p[p1]+a*t<p[i])
		{
			f1[p1]=0;
			f2[p1]=1;
			double tmp=p[i]-p[p1]-a*t;
			q2.push((node){p1,f[p1]+tmp/b+t});
			p1++;
		}
		while(p2<p1&&p[p2]+a*t+b*r<p[i])
		{
			f2[p2]=0;
			double tmp=p[i]-p[p2]-a*t-b*r;
			ans=min(ans,f[p2]+tmp/a+t+r-p[i]/a);
			p2++;
		}
		while(!q1.empty()&&!f1[q1.top().p])
			q1.pop();
		while(!q2.empty()&&!f2[q2.top().p])
			q2.pop();
		f[i]=ans+p[i]/a;
		if(!q1.empty())f[i]=min(f[i],q1.top().val+p[i]/a);
		if(!q2.empty())f[i]=min(f[i],q2.top().val);
	}
	printf("%.9lf",f[n]);
}
posted @ 2018-10-29 12:41  风浔凌  阅读(315)  评论(0编辑  收藏  举报