遇到这一类变量要求比较多的题目完全不知道该从哪里下手啊
感觉这个题用记忆化搜索写才方便
我们每次搜索上一个平台,递归计算出从左侧下来和右侧下来用时
并取其较小者
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1010
#define INF 100000000
using namespace std;
int leftmin[MAXN], rightmin[MAXN];
int n, X, Y, MAX;
struct Platform {
int l, r, h;
}p[MAXN];
bool cmp(Platform a, Platform b) {
return a.h > b.h;
}
int mintime(int cur, int flag) { //用flag标志向左或向右
int x, h, i, ltime, rtime;
h = p[cur].h;
if(flag) {
x = p[cur].l;
} else x = p[cur].r;
for(i=cur+1; i<=n; ++i) {
if(p[i].l<=x && p[i].r>=x) //可以从当前位置跳到第i个平台上
break;
}
if(i <= n) {
if(h-p[i].h > MAX)
return INF;
} else {//到达底部平台
if(h > MAX)
return INF;
return h;
}
ltime = rtime = h-p[i].h;
ltime += x-p[i].l;
rtime += p[i].r-x;
if(leftmin[i] == -1) //记忆化搜索
leftmin[i] = mintime(i, 1);
if(rightmin[i] == -1)
rightmin[i] = mintime(i, 0);
ltime += leftmin[i];
rtime += rightmin[i];
return ltime > rtime ? rtime : ltime;
}
int main(void) {
int T;
scanf("%d", &T);
while(T--) {
memset(leftmin, -1, sizeof(leftmin));
memset(rightmin, -1, sizeof(rightmin));
scanf("%d%d%d%d", &n, &X, &Y, &MAX);
p[0].l = X;
p[0].r = X;
p[0].h = Y;
for(int i=1; i<=n; ++i) {
scanf("%d%d%d", &p[i].l, &p[i].r, &p[i].h);
}
sort(p, p+n+1, cmp);
printf("%d\n", mintime(0, 1));
}
return 0;
}