【题意】
场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。
Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。
设计一个程序,计算Jimmy到底地面时可能的最早时间。
【分析】一个结构体f[i],里面有两个值,一个是从起始点到左端点最短时间,一个是右端点;然后就很简单了,对于每一个横台(hentai?2333)就用左右端点去更新下面横台的结果。记得要按高度排序
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct p{
long long l, r, h;
} a[2000];
struct pro{
long long l, r;
};
int cmp(p a, p b){
return a.h > b.h;
}
int main(){
int T;
cin >> T;
while(T--){
int n, k;
pro f[2000];
memset(a, 0, sizeof(a));
cin >> n >> a[1].l >> a[1].h >> k;
a[1].r = a[1].l;
for(int i = 2; i <= n + 1; i ++){
cin >> a[i].l >> a[i].r >> a[i].h;
f[i].l = f[i].r = 1e15;
}
f[1].l = f[1].r = 0;
f[n + 2].l = 1e15;
sort(a + 1, a + 2 + n, cmp);
for(int i = 1; i <= n + 1; i++){
for(int j = i + 1; j <= n + 2; j++){
if(a[i].h - a[j].h > k) break;
if(j == n + 2){
f[j].l = min(f[j].l, f[i].l + a[i].h);
}
if(a[i].l <= a[j].r && a[i].l >= a[j].l){
f[j].l = min(f[j].l, f[i].l + a[i].h - a[j].h + a[i].l - a[j].l);
f[j].r = min(f[j].r, f[i].l + a[i].h - a[j].h + a[j].r - a[i].l);
break;
}
}
for(int j = i + 1; j <= n + 2; j++){
if(a[i].h - a[j].h > k) break;
if(j == n + 2){
f[j]. l = min(f[j].l, f[i].r + a[i].h);
}
if(a[i].r <= a[j].r && a[i].r >= a[j].l){
f[j].l = min(f[j].l, f[i].r + a[i].h - a[j].h + a[i].r - a[j].l);
f[j].r = min(f[j].r, f[i].r + a[i].h - a[j].h + a[j].r - a[i].r);
break;
}
}
}
cout << f[n + 2].l << endl;
}
return 0;
}