没刷过 POJ,这题是论坛有人问的,我才看看。

我发现 POJ 注册很奇怪,账号总是登不上去,弄的我还注册两个。Emmm 首次体验很差,还好我不在 POJ 刷题。

题目链接:POJ 1661 Help Jimmy


解题思路

我最初想的是用递归从上往下不断选择方向,结果发现我有点傻了,这样极有可能 TLE。

其实应该是用动态规划解题。从下往上,将每块平台的左端点和右端点到地面的最短时间计算出来。最后得到人的最短时间。

思路详解:

很明显,平台有三个数据,左端点,右端点,高度。因此直接定义结构体如下:

typedef struct Node {
int left, right, height;
}Platform;// 平台
Platform plat[MAX_N];// 所有平台信息

这里有个细节就是将地面都看做平台。地面和人的数据如下:

// 地面,地面高度最小,故保存在数组第一个
plat[0].left = -20000;
plat[0].right = 20000;
plat[0].height = 0;
// 人,人高度最大,故保存在数组最后一个
plat[platNum - 1].left = plat[platNum - 1].right = x;
plat[platNum - 1].height = y;

升序排序。一如既往的使用 qsort 函数,自定义比较函数 compare

从下往上遍历每个平台,分别计算左右端点的最短时间。保存在二维数组 time[MAX_N][2] 中。

计算数组的方法(以 time[i][0] 为例,ij 表示平台):

遍历 i 下方的平台,找到一个人不会摔死的平台 j。(如果会摔死,说明 i 的端点 dir 是悬崖,退出 down 函数)

如果找到 j 位于 i 的下方。判断 j 是不是地面。

如果是地面,那么 i 的高度就是 i 的端点 dir 的最短时间。time[i][dir] = plat[i].height

如果不是地面,那么 j 是平台(不包括地面),如下图所示:



补充:图中的 h 改为 th

需要注意的是,time[j][0]time[j][1] 本身可能就是悬崖。具体看代码的 if 条件判断。这种情况有其他处理方法,暂且不表。

如果都不是悬崖,那么状态转移方程为:time[i][dir] = MIN(time[j][0] + tl, time[j][1] + tr) + th;

thtltr 这三个量很容易计算。不做说明。

因此最后的 time[i][0],其中 i 是人的下标,即为最终结果。

时间复杂度:main 函数里面有一个 for 循环,down() 里面有 for 循环。故为 O(n2)O(n^2)O(n2) 。

空间复杂度:结构体数组加上一个二维数组,总共不低于 O(n)O(n)O(n)。

C代码

#include<stdio.h>
#include<stdlib.h>
#include<limits.h>// INT_MAX头文件 #define MAX_N 1003
#define MIN(a, b) (((a) < (b)) ? (a) : (b)) typedef struct Node {
int left, right, height;
}Platform;// 平台
Platform plat[MAX_N];// 所有平台信息
int platNum;// 平台个数 int time[MAX_N][2];// 平台左端点和右端点到地面的最短时间 int maxHeight;// 每次下落的最大高度 int compare(const Platform* a, const Platform* b) {// 比较函数,平台高度升序
return (*a).height - (*b).height;
} // 下落
// i 当前平台
// dir 下落后选择的方向,0表示左,1表示右
// x 平台i的端点横坐标,必须与dir对应
void down(int i, int dir, int x) {
// 查找i正下方的j
int j;
for (j = i - 1; j >= 0; --j) {
if (plat[i].height - plat[j].height > maxHeight) {// i和j的高度差超过最大值
time[i][dir] = INT_MAX;// 人会摔死,因此时间为正无穷,表示悬崖
return;
}
if (x >= plat[j].left && x <= plat[j].right) {// j在i正下方
break;// 已找到,退出循环
}
} if (j == 0) {// j是地面
time[i][dir] = plat[i].height;// i的高度就是i的端点dir最短时间
return;
} // j是平台(不包括地面),计算i的端点dir到地面的最短时间
int tl = x - plat[j].left;// i的端点到j的左端点的水平时间
int tr = plat[j].right - x;// i的端点到j的右端点的水平时间
int th = plat[i].height - plat[j].height;// i到j的垂直下落时间
if (time[j][0] == INT_MAX) {// j左边是悬崖
if (time[j][1] == INT_MAX) {// j右边是悬崖
time[i][dir] = INT_MAX;// 那么i的端点dir也是悬崖
} else {
time[i][dir] = time[j][1] + tr + th;// 走j的右边
}
} else {
if (time[j][1] == INT_MAX) {
time[i][dir] = time[j][0] + tl + th;// 走j的左边
} else {// j的左边和右边都不是悬崖,选择j的时间短的方向
time[i][dir] = MIN(time[j][0] + tl, time[j][1] + tr) + th;
}
}
} int main() {
int t, n, x, y, max; scanf("%d", &t);// 样例数
while (t--) {
scanf("%d %d %d %d", &n, &x, &y, &max); maxHeight = max;// 每次下落的最大高度 platNum = n + 2;// 平台,人,地面。共n+2个“平台” // 地面,地面高度最小,故保存在数组第一个
plat[0].left = -20000;
plat[0].right = 20000;
plat[0].height = 0;
// 人,人高度最大,故保存在数组最后一个
plat[platNum - 1].left = plat[platNum - 1].right = x;
plat[platNum - 1].height = y; // 输入所有平台的左右端点坐标和高度
for (int i = 1; i < platNum - 1; ++i) {
scanf("%d %d %d", &plat[i].left, &plat[i].right, &plat[i].height);
} qsort(plat, platNum, sizeof(Platform), compare);// 平台按照高度升序 time[0][0] = time[0][1] = 0;// 地面时间为0 for (int i = 1, j; i < platNum; ++i) {// 从下往上计算每个平台的最短用时
down(i, 0, plat[i].left);// 从i下落后走左边
down(i, 1, plat[i].right);// 从i下落后走右边
} printf("%d\n", time[platNum - 1][0]);// 输出人到地面的最短用时
} return 0;
}

提交结果

POJ 1661 Help Jimmy(C)动态规划的更多相关文章

  1. POJ 1661 Help Jimmy(递推DP)

    思路: 1. 每个板子有左右两端, dp[i][0], dp[i][1] 分别记录左右端到地面的时间 2. 从下到上递推计算, 上一层的板子必然会落到下面的某一层板子上, 或者地面上 总结: 1. 计 ...

  2. POJ 1661 Help Jimmy -- 动态规划

    题目地址:http://poj.org/problem?id=1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度 ...

  3. OpenJudge/Poj 1661 帮助 Jimmy

    1.链接地址: bailian.openjudge.cn/practice/1661 http://poj.org/problem?id=1661 2.题目: 总Time Limit: 1000ms ...

  4. POJ 1661 Help Jimmy(DP/最短路)

    Help Jimmy Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14980 Accepted: 4993 Descripti ...

  5. POJ 1661 Help Jimmy(二维DP)

    题目链接:http://poj.org/problem?id=1661 题目大意: 如图包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的 ...

  6. POJ - 1661 - Help Jimmy - 简单dp

    http://poj.org/problem?id=1661 一般化处理,把一开始的落地和大地都视作平台,设计平台类的属性.dp的时候显然是从上往下dp的,而且要小心Jimmy不能够穿过平台,也就是从 ...

  7. POJ 1661 Help Jimmy【DP】

    基础DP,过程想明白了其实也不复杂,从上面的推下面的比倒着推要简单很多.调试了半个多小时..简单dp依然不能快速AC..SAD.. 题目链接: http://poj.org/problem?id=16 ...

  8. POJ 1661 Help Jimmy LIS DP

    http://poj.org/problem?id=1661 对板按高度排序后. dp[i][0]表示现在站在第i块板上,向左跑了,的状态,记录下时间和其他信息. O(n^2)LIS: 唯一的麻烦就是 ...

  9. POJ 1661 Help Jimmy (dijkstra,最短路)

    刚在百度搜索了一下这道题的题解, 因为看到有别人用动态规划做的,所以想参考一下. 结果顺带发现了有那么几个网站,上面的文章竟然和我这篇一模一样(除了一些明显的错别字外),我去,作者还是同一个人Admi ...

随机推荐

  1. learning java 使用WatchService监控文件变化

    import java.io.IOException; import java.nio.file.*; public class WatchServiceTest { public static vo ...

  2. WinDbg常用命令系列---异常相关操作

    .exr (Display Exception Record) .exr命令显示异常记录的内容. .exr Address .exr -1 参数: Address指定异常记录的地址.如果指定-1作为地 ...

  3. 48、Spark SQL之与Spark Core整合之每日top3热点搜索词统计案例实战

    一.概述 1.需求分析 数据格式: 日期 用户 搜索词 城市 平台 版本 需求: 1.筛选出符合查询条件(城市.平台.版本)的数据 2.统计出每天搜索uv排名前3的搜索词 3.按照每天的top3搜索词 ...

  4. USACO 重排干草&&BZOJ1045

    USACO 重排干草&&BZOJ1045 Description 约翰订购了很多干草,他在农场里标记了 N 个位置.这些位置近似地构成一个圆环.他原打算 让送货司机在 i 号位卸下 B ...

  5. 【Excel】定位条件快速将空值替换为指定值

    现有如下表格,表格中存在一些空值,如下图: 目的 将上图的空值全部赋值为100,实现后效果如下: 实现步骤 1.选中数字区域,按CTRL+G 2.点击[定位条件]后,选择[空值]后[确定] 3.在编辑 ...

  6. 《JAVA程序设计》_第十周学习总结

    一.学习内容 12.1进程与进程 程序是一段静态的代码,进程是程序的一次动态执行过程,这个过程也是进程本身从产生.发展至消亡的过程. 线程不是进程,是比进程更小的执行单位.但与进程不同的是,线程的中断 ...

  7. crontab定时任务接入

    # 查看 $ crontab -l # 创建 $ crontab -e # 每分钟输出一次当前时间 * * * * * echo `date` >> /demo.log # 查看定时 $ ...

  8. Unity3D新手入门初级教程

    根据游戏调查公司 Newzoo 针对全球手机游戏市场所做的调查报告显示,2016年全球游戏市场规模将达到 996 亿美元,其中手机游戏市场将以 21.3% 的增幅获得约 369 亿美元的收入,而中国手 ...

  9. NGINX Cache Management (.imh nginx)

    In this article, we will explore the various NGINX cache configuration options, and tips on tweaking ...

  10. SpringMVC 给请求路径加上统一前缀

    最开始想到的是通过硬编码的方式手动在每个路径上加上前缀, 后面发现这种方式太不智能了,万一要修改那还不得改死, Spring既然支持EL表达式, 那能不能通过EL表达式的方式去读取配置文件里面的属性来 ...