poj 1661 Help Jimmy(DP:记忆化搜索)

来源:互联网 发布:淘宝卖家开通花呗好吗 编辑:程序博客网 时间:2024/04/29 08:58

遇到这一类变量要求比较多的题目完全不知道该从哪里下手啊

感觉这个题用记忆化搜索写才方便

我们每次搜索上一个平台,递归计算出从左侧下来和右侧下来用时

并取其较小者

代码如下:

#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 1010#define INF 100000000using 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;}


0 0