题意:有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;
}
本文探讨了一种基于贪心思想和动态规划的算法,用于解决在有限马匹资源下从起点到终点的最短时间问题。通过排序和维护好马区间,实现高效的路径选择。

2117

被折叠的 条评论
为什么被折叠?



