题意:有n(1<=n<=5000)个驿站,所有驿站的总和有最多m(1<=m<=10^5)匹马,每匹马有属性d v代表从当前的驿站出发能走d距离远,速度为v
(匀速),问一个人从起点0走到b(1<=b<=10^8)的最短的时间是多少。
题解:首先对每一个驿站的马进行排序,相同d的取v大的,如果一匹马比当前的马d大而且v大那么当前的马就是死马,这里体现的是贪心的思想,然后对于
每一个驿站维护出可行的好马区间,接下来是dp的过程,枚举每一个驿站,用一个指针扫描马,对于以后的驿站扫描到的最后一个能到达当前驿站的
一定是速度最大的,O(1)的转移,整体时间复杂度O(m + n * n)可以接受。
Sure原创,转载请注明出处
#include <iostream> #include <cstdio> #include <memory.h> #include <algorithm> #define MAX(a , b) ((a) > (b) ? (a) : (b)) #define MIN(a , b) ((a) < (b) ? (a) : (b)) using namespace std; const int maxn = 5002; const int maxh = 100002; struct HH { int pos; int d,v; bool operator < (const HH &other) const { if(pos == other.pos) { if(d == other.d) { return v > other.v; } return d > other.d; } return pos < other.pos; } }horse[maxh]; struct SS { int pos; int fr,to; }stable[maxn]; double dp[maxn]; int b,n,tot,top,cnt; void read() { tot = top = cnt = 0; int p,num; for(int i=0;i<n;i++) { scanf("%d %d",&p,&num); for(int j=0;j<num;j++) { horse[tot].pos = p; scanf("%d %d",&horse[tot].v,&horse[tot].d); tot++; } } return; } void make() { sort(horse , horse + tot); while(tot > 0 && horse[tot-1].pos >= b) tot--; horse[tot].pos = b; horse[tot].d = horse[tot].v = 0; tot++; for(int i=0;i<tot;) { stable[cnt].pos = horse[i].pos; stable[cnt].fr = top; horse[top++] = horse[i]; int maxv = horse[i].v,j; for(j=i+1;j<tot && horse[j].pos == horse[i].pos;j++) { if(horse[j].d == horse[j-1].d || horse[j].v <= maxv) continue; horse[top++] = horse[j]; maxv = MAX(maxv , horse[j].v); } i = j; stable[cnt++].to = top-1; } return; } void solve() { if(stable[0].pos > 0) { puts("-1"); return; } for(int i=1;i<cnt;i++) { dp[i] = 1e100; } dp[0] = 0; for(int i=0;i<cnt;i++) { int end = stable[i].to; for(int j=i+1;j<cnt;j++) { while(end >= stable[i].fr && stable[i].pos + horse[end].d < stable[j].pos) end--; if(end < stable[i].fr) break; dp[j] = MIN(dp[j] , dp[i] + (double)(stable[j].pos - stable[i].pos) / horse[end].v); } } if(dp[cnt-1] == 1e100) puts("-1"); else printf("%.8f\n",dp[cnt-1]); return; } int main() { while(~scanf("%d %d",&b,&n)) { read(); make(); solve(); } return 0; }