出行(动态规划)(单调队列优化)
用优先队列实现的代码:
#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]);
}