【MX-S6-T2】「KDOI-11」飞船 题解
前言
典中典。
Solution
显然速度达到一定大小的时候再往上加一定不优,由
我们可以设个上限值,然后在上限值范围内进行 dp。
但是我们发现
于是我们可以设
然后就做完了,时间复杂度为
Code
#include<bits/stdc++.h>
#include<cmath>
#define ll long long
#define lll __int128
#define ull unsigned long long
#define N 100010
#define For(i,a,b) for(int i=a;i<=b;++i)
#define Rof(i,a,b) for(int i=a;i>=b;--i)
#define ls x<<1
#define rs x<<1|1
#define lson ls,l,mid
#define rson rs,mid+1,r
#define pb push_back
#define mk make_pair
#define pque priority_queue
#define pii pair<int,int>
using namespace std;
bool st;
const double inf=1e12;
double f[2][35][35];
struct node{
int x,t,num;
}a[N];
struct ask{
int t,bh;
}b[N];
double ans[N];
int n,q;
bool ed;
ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
//fprintf(stderr,"%.2lf",(double)(&ed-&st)/1024/1024);
//freopen("ship.in","r",stdin);
//freopen("ship.out","w",stdout);
n=read(),q=read();
For(i,1,n) a[i].x=read(),a[i].t=read(),a[i].num=read();
For(i,1,q) b[i].t=read(),b[i].bh=i;
sort(b+1,b+q+1,[&](ask x,ask y){return x.t<y.t;});
For(i,0,1){
For(j,0,34){
For(k,0,34){
f[i][j][k]=inf;
}
}
}
f[0][0][0]=0;
int now=0;
For(i,1,q){
while(now<n && a[now+1].x<=b[i].t){
int op=now&1;
double now1=1;
For(j,0,34){
double now2=now1;
For(k,0,34){
if(now2>inf) break;
f[op^1][j][k]=f[op][j][k]+(double)(a[now+1].x-a[now].x)*1.0/now2;
now2*=3;
}
now1*=2;
}
int p1=0,p2=0;
if(a[now+1].num==2) p1=1;
else if(a[now+1].num==3) p2=1;
else if(a[now+1].num==4) p1=2;
now1=1;
For(j,0,34-p1){
double now2=now1;
For(k,0,34-p2){
if(now2>inf) break;
f[op^1][j+p1][k+p2]=min(f[op^1][j+p1][k+p2],f[op][j][k]+(double)(a[now+1].x-a[now].x)*1.0/now2+(double)a[now+1].t);
now2*=3;
}
now1*=2;
}
now++;
}
double now1=1,nowans=inf;
For(j,0,34){
double now2=now1;
For(k,0,34){
if(now2>inf) break;
nowans=min(nowans,f[now&1][j][k]+(double)(b[i].t-a[now].x)*1.0/now2);
now2*=3;
}
now1*=2;
}
ans[b[i].bh]=nowans;
}
For(i,1,q) printf("%.10lf\n",ans[i]);
return 0;
}
/*
*/