• POJ


    Help Jimmy

    题目大意:

    Description

    “Help Jimmy” 是在下图所示的场景上完成的游戏。

    场景中包括多个长度和高度各不相同的平台。地面是最低的平台,高度为零,长度无限。

    Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒。当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒。当Jimmy跑到平台的边缘时,开始继续下落。Jimmy每次下落的高度不能超过MAX米,不然就会摔死,游戏也会结束。

    设计一个程序,计算Jimmy到底地面时可能的最早时间。
    Input

    第一行是测试数据的组数t(0 <= t <= 20)。每组测试数据的第一行是四个整数N,X,Y,MAX,用空格分隔。N是平台的数目(不包括地面),X和Y是Jimmy开始下落的位置的横竖坐标,MAX是一次下落的最大高度。接下来的N行每行描述一个平台,包括三个整数,X1[i],X2[i]和H[i]。H[i]表示平台的高度,X1[i]和X2[i]表示平台左右端点的横坐标。1 <= N <= 1000,-20000 <= X, X1[i], X2[i] <= 20000,0 < H[i] < Y <= 20000(i = 1..N)。所有坐标的单位都是米。

    Jimmy的大小和平台的厚度均忽略不计。如果Jimmy恰好落在某个平台的边缘,被视为落在平台上。所有的平台均不重叠或相连。测试数据保证问题一定有解。
    Output

    对输入的每组测试数据,输出一个整数,Jimmy到底地面时可能的最早时间。
    Sample Input

    1
    3 8 17 20
    0 10 8
    0 10 13
    4 14 3
    Sample Output

    23
    Source

    POJ Monthly–2004.05.15 CEOI 2000

    解题思路:

    这道题写着比较繁琐,但是思路其实并不算太复杂,因为从上面掉下来只有两种情况,要么从左边下来,要么从右边下来,而从高处下来的话只要事先知道比它低的所有的最小值了,那么自然可以求出相应位置的最小值,这里用dp[0][i]代表从第i块高的板左边落地的最小时间,相应的dp[1][i]代表从右边落地的最短时间,转移方程为:
    从左边走:
    dp[0][i]=min(dp[0][i],min(dp[0][j]+num[i].lnum[j].l,dp[1][j]+num[j].rnum[i].l)+num[i].hnum[j].h).
    从右边走:
    dp[1][i]=min(dp[1][i],min(dp[0][j]+num[i].rnum[j].l,dp[1][j]+num[j].rnum[i].r)+num[i].hnum[j].h).

    AC代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    const int maxn = 1000;
    const int INF = 1e9 + 7;
    struct NOOD {
        int l, r, h;
    }num[maxn + 5];
    int dp[2][maxn + 5];
    int n, Max, x, h;
    int T;
    bool cmp(NOOD x, NOOD y) {
        return x.h < y.h;
    }
    void Init() {
        scanf("%d%d%d%d", &n, &x, &h, &Max);
        for(int i = 1; i <= n; i++) {
            scanf("%d%d%d", &num[i].l, &num[i].r, &num[i].h);
        }
        num[0].l = -20000;
        num[0].r = 20000;
        num[0].h = 0;
        num[++n].l = num[n].r = x;
        num[n].h = h;
        sort(num, num + n + 1, cmp);
        for(int i = 1; i <= n; i++)dp[0][i] = dp[1][i] = INF;
        dp[0][0] = 0;
        dp[1][0] = 0;
    }
    int main() {
        scanf("%d", &T);
        while(T--) {
            Init();
            for(int i = 1; i <= n; i++) {
                int flag1 = 0;
                int flag2 = 0;
                for(int j = i - 1; j >= 0; j--) {
                    if(flag1 && flag2)break;//因为是从高处到低处的,所以左边右边都已经有过就不会再到下面了
                    if(num[i].l <= num[j].r && num[i].l >= num[j].l && !flag1) {//从左端点下去时,判断能否到达上面
                        flag1 = 1;
                        if(num[i].h - num[j].h <= Max) {//要不能被摔死
                            if(j != 0)dp[0][i] = min(dp[0][i], min(dp[0][j] + num[i].l - num[j].l, dp[1][j] + num[j].r - num[i].l) + num[i].h - num[j].h);
                            else dp[0][i] = min(dp[0][i], num[i].h);
                        }
                    }
                    if(num[i].r >= num[j].l && num[i].r <= num[j].r && !flag2){//从右端点下去时,判断能否到达上面
                        flag2 = 1;
                        if(num[i].h - num[j].h <= Max) {
                            if(j != 0)dp[1][i] = min(dp[1][i], min(dp[0][j] + num[i].r - num[j].l, dp[1][j] + num[j].r - num[i].r) + num[i].h - num[j].h);
                            else dp[1][i] = min(dp[1][i], num[i].h);
                        }
                    }
                }
            }
            printf("%d
    ", min(dp[0][n], dp[1][n]));//最后输出从左边和右边落地的最小时间
        }
        return 0;
    }
  • 相关阅读:
    R语言中基于混合数据抽样(MIDAS)回归的HAR-RV模型预测GDP增长
    R语言马尔可夫体制转换模型Markov regime switching
    php设计模式--简单介绍
    css字体图标的使用方法
    linux系统管理--top命令
    linux系统管理--查看进程
    linux系统管理--进程管理
    用户体验时代的9条建议
    【转】纯手工玩转 Nginx 日志
    【转】一分钟内检查Linux服务器性能
  • 原文地址:https://www.cnblogs.com/TRDD/p/9813524.html
Copyright © 2020-2023  润新知