zoukankan      html  css  js  c++  java
  • 动规-POJ-1661

    http://poj.org/problem?id=1661

    Help Jimmy

    在同一竖直平面上,存在地面(高度为0,长度无限),以及若干个给定高度的水平平台(高度、左右端点给定)。

    现有Jimmy从给定点(x, y)跳下,下落的速度恒为1单位距离/单位时间。但下落的距离不能超过给定的高度MAX,否则Jimmy就会摔死。

    若Jimmy降落在某一个平台上,那么Jimmy可以选择从平台的左端点或者右端点继续跳下。

    问:Jimmy到达地面的最短时间。

    保证Jimmy一定有办法安全降落到地面。

    保证没有重叠的平台。

    若Jimmy恰好落在平台的左端点或者右端点,也算作Jimmy跳到这个平台上。

    解题报告

    思路

    首先,可以把题设中的其实点和地面也抽象为平台加入平台数组中。

    每个平台都有从左跳和从右跳两种选择,且跳之后的落点是确定的,跳之前的状态不影响跳之后的状态转移,没有后效性——动态规划。

    首先将平台数组按高度排序。

    随后建立数组dp[i][j]表示,Jimmy达到第i个平台的j端点时,需要的最短时间。

    初始化dp[0][0] = dp[0][1] = 1(初始点时间花费为0)

    从高到低遍历每个平台,枚举从平台左右端点跳下的情况.

    假设从i平台的j端点跳下以后,能安全到达k平台,那么:

    dp[k][0] = min(dp[k][0], dp[i][j] + 高度差 + 从k平台上的落点到0端点的时间花费)

    dp[k][1] = min(dp[k][1], dp[i][j] + 高度差 + 从k平台上的落点到1端点的时间花费)

    要注意,下落过程不能穿过平台,所以每个平台跳下过程最多从左右端点各转移一次。

    当然,到达地面以后不需要跑到左右端点,所以要特判一下到达地面的情况。

    最后输出min( dp[地面][0], dp[地面][1] )即可

    代码

    #include <algorithm>
    #include <cstring>
    #include <iostream>
    
    using namespace std;
    
    const int maxn = 1003;
    const int INF = 20004;
    
    struct Platform {
        int l, r, h;
        Platform(int _l = 0, int _r = 0, int _h = 0) : l(_l), r(_r), h(_h) {}
        bool operator<(const Platform &Right) const {
            return h > Right.h;
        }
    } platform[maxn];
    
    int n, t, cnt;
    int stx, sty, maxh;
    int top;
    
    int dp[maxn][2];
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> t;
        while (t--) {
            cin >> n >> stx >> sty >> maxh;
            cnt = 0;
            for (int i = 0; i < n; i++) {
                int l, r, h;
                cin >> l >> r >> h;
                if (h > sty || (h == sty && (stx < l || stx > r))) continue;
                platform[cnt++] = Platform(l, r, h);
            }
            platform[cnt++] = Platform(stx, stx, sty);
            platform[cnt++] = Platform(-INF, INF, 0);
            sort(platform, platform + cnt);
            memset(dp, 0x3f3f3f3f, sizeof(dp));
            dp[0][0] = dp[0][1] = 0;
            for (int i = 0; i < cnt - 1; i++) {
                bool flagl = false, flagr = false;
                for (int j = i + 1; j < cnt && platform[i].h - platform[j].h <= maxh; j++) {
                    if(flagl && flagr) break;
                    if (platform[i].l >= platform[j].l && platform[i].l <= platform[j].r && !flagl) {
                        dp[j][0] = min(dp[j][0], dp[i][0] + platform[i].h - platform[j].h + platform[i].l - platform[j].l);
                        dp[j][1] = min(dp[j][1], dp[i][0] + platform[i].h - platform[j].h + platform[j].r - platform[i].l);
                        if (j == cnt - 1) {
                            dp[j][0] = min(dp[j][0], dp[i][0] + platform[i].h - platform[j].h);
                            dp[j][1] = min(dp[j][1], dp[i][0] + platform[i].h - platform[j].h);
                        }
                        flagl = true;
                    }
                    if (platform[i].r >= platform[j].l && platform[i].r <= platform[j].r && !flagr) {
                        dp[j][0] = min(dp[j][0], dp[i][1] + platform[i].h - platform[j].h + platform[i].r - platform[j].l);
                        dp[j][1] = min(dp[j][1], dp[i][1] + platform[i].h - platform[j].h + platform[j].r - platform[i].r);
                        if (j == cnt - 1) {
                            dp[j][0] = min(dp[j][0], dp[i][1] + platform[i].h - platform[j].h);
                            dp[j][1] = min(dp[j][1], dp[i][1] + platform[i].h - platform[j].h);
                        }
                        flagr = true;
                    }
                }
            }
            cout << min(dp[cnt - 1][0], dp[cnt - 1][1]) << endl;
        }
        return 0;
    }

    --(完)-- 

  • 相关阅读:
    apache-atlas 深度剖析
    Robot Framework自动化测试框架核心指南-如何使用Java编写自定义的RobotFramework Lib
    Hbase架构剖析
    Mysql 执行计划以及常见索引问题总结
    RobotFramework自动化测试框架-Selenium Web自动化(三)关于在RobotFramework中如何使用Selenium很全的总结(下)
    kafka connector 使用总结以及自定义connector开发
    flink 流式处理中如何集成mybatis框架
    RobotFramework自动化测试框架-Selenium Web自动化(二)关于在RobotFramework中如何使用Selenium很全的总结(上)
    一次flume exec source采集日志到kafka因为单条日志数据非常大同步失败的踩坑带来的思考
    MongoDB Java API操作很全的整理以及共享分片模式下的常见操作整理
  • 原文地址:https://www.cnblogs.com/Bcai0797/p/6985498.html
Copyright © 2011-2022 走看看