POJ 1661 Help Jimmy (一个神trick)

小人从上往下掉的时候,比如区间[-50, 100], [0, 100]它可以从上一个100跳到下一个100.。。。。无语的神逻辑。。。从早晨wa到现在。T_T

按高度从大到小排序

f[i][0]表示到i层左端点的最小路径,f[i][1]表示到i层右端点的最小路径。

落下时判断第j层到第i层有没有其他的层。。。这个写了一个暴力,居然没有TLE。。。看来题目数据真的不怎么强。

View Code
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <set>
#include <ctime>
#include <queue>
#include <map>
#include <sstream>

#define CL(arr, val)    memset(arr, (val), sizeof(arr))
#define REP(i, n)       for((i) = 0; (i) < (n); ++(i))
#define FOR(i, l, h)    for((i) = (l); (i) <= (h); ++(i))
#define FORD(i, h, l)   for((i) = (h); (i) >= (l); --(i))
#define L(x)    (x) << 1
#define R(x)    (x) << 1 | 1
#define MID(l, r)   ((l) + (r)) >> 1
#define Min(x, y)   (x) < (y) ? (x) : (y)
#define Max(x, y)   (x) < (y) ? (y) : (x)
#define E(x)    (1 << (x))
#define iabs(x)  ((x) > 0 ? (x) : -(x))

typedef long long LL;
const double eps = 1e-8;
const int inf = ~0u>>2;

using namespace std;

const int N = 1024;

struct node {
    int x1, x2, h;
    bool operator < (const node tmp) const {
        return h > tmp.h;
    }
} l[N];

int f[N][2];

int main() {
    //freopen("data.in", "r", stdin);

    int t, n, x, y, mx;
    int i, j, k, tmp;
    bool flag;

    scanf("%d", &t);
    while(t--) {
        scanf("%d%d%d%d", &n, &x, &y, &mx);
        l[0].x1 = x; l[0].x2 = x; l[0].h = y;

        for(i = 1; i <= n; ++i) {
            scanf("%d%d%d", &l[i].x1, &l[i].x2, &l[i].h);
            f[i][1] = f[i][0] = inf;
        }
        sort(l, l + n + 1);
        f[0][0] = f[0][1] = 0;

        /*for(i = 0; i <= n; ++i) {
            printf("%d %d %d\n", l[i].x1, l[i].x2, l[i].h);
        }*/

        for(i = 1; i <= n; ++i) {
            for(j = 0; j < i; ++j) {
                if(l[i].x1 <= l[j].x1 && l[i].x2 >= l[j].x1 && l[j].h - l[i].h <= mx) {

                    //left
                    flag = true;
                    for(k = j + 1; k < i && flag; ++k)  {
                        if(l[k].x1 <= l[j].x1 && l[k].x2 >= l[j].x1)  {flag = false; break;}
                    }
                    if(flag && f[j][0] != inf) {
                        tmp = f[j][0] + l[j].h - l[i].h + iabs(l[j].x1 - l[i].x1);
                        f[i][0] = min(f[i][0], tmp);

                        tmp = f[j][0] + l[j].h - l[i].h + iabs(l[j].x1 - l[i].x2);
                        f[i][1] = min(f[i][1], tmp);
                    }
                }

                //right
                if(l[i].x1 <= l[j].x2 && l[i].x2 >= l[j].x2 && l[j].h - l[i].h <= mx) {
                    flag = true;
                    for(k = j + 1; k < i && flag; ++k) {
                        if(l[k].x1 <= l[j].x2 && l[k].x2 >= l[j].x2)  {flag = false; break;}
                    }
                    if(flag && f[j][1] != inf) {
                        tmp = f[j][1] + l[j].h - l[i].h + iabs(l[j].x2 - l[i].x1);
                        f[i][0] = min(f[i][0], tmp);

                        tmp = f[j][1] + l[j].h - l[i].h + iabs(l[j].x2 - l[i].x2);
                        f[i][1] = min(f[i][1], tmp);
                    }
                }
            }
        }

        int ans = inf;
        for(i = 0; i <= n; ++i) {
            if(l[i].h <= mx) {
                //left
                flag = true;
                for(k = i + 1; k <= n; ++k) {
                    if(l[k].x1 <= l[i].x1 && l[k].x2 >= l[i].x1)  {flag = false; break;}
                }
                if(flag) {
                    tmp = f[i][0] + l[i].h;
                    ans = min(tmp, ans);
                }

                //right
                flag = true;
                for(k = i + 1; k <= n; ++k) {
                    if(l[k].x1 < l[i].x2 && l[k].x2 > l[i].x2)  {flag = false; break;}
                }
                if(flag) {
                    ans = min(ans, f[i][1] + l[i].h);
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

 

 

 

 

posted @ 2012-08-07 10:22  AC_Von  阅读(1059)  评论(0编辑  收藏  举报