感觉蛮坑的一道题。

题意很像一个叫“是男人下100层”的游戏。不过多了个时间限制,要求在限定时间内从某一点下落到地面。还多了个最大下落高度,一次最多下落这么高,要不然会摔死。

一开始想dp的,然后想了半天想不到状态,因为如果以下落点位状态的话,一个板子上会有许多状态,然后就没法继续下去了。

然后试着证明贪心,结果证明不出来。贪心也用不了了。

其实放弃了,在比赛结束后又去看了看,然后讨论,然后吧啦吧啦吧啦……还是做不出来。结果还是搜了题解,唉,有些挫败感。

输入:

首行输入整数t,表示共t组数据。

接下来每组数据首行输入n, x, h, maxn, m。分别表示板子数量,初始位置的横坐标,初始位置的高度,最大一次可以下落的高度,限定时间。

接下来n行,每行3个整数,l, r, h。表示第i个板子的左边的坐标,右边的左边,高度。

输出:

如果在m秒内(含m秒)能到达地面,输出“NO”,否则输出“YES”。

题解用的还是dp,只是他稍微拐了个弯,设的状态是每块板子的左端坐标和右端坐标,这样就解决了从不同高板子下落到同一低板子上时会产生不同状态的问题了,不得不感慨,dp真神奇。

核心——判断从第i块板子上的左,右端下落到第j块板子的左,右端(如果可以的话)是否优于原本第j块板子左右端的时间。

 #include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int N = ; struct Tp
{
int l, r, h;
}tp[N]; int dp[N][];
int x, maxn, h;
int n, m, t; bool cmp(Tp x, Tp y)
{
return x.h > y.h;
} void init()
{
scanf("%d%d%d%d%d", &n, &x, &h, &maxn, &m);
tp[].l = x; tp[].r = x; tp[].h = h; //出发点也设为一个板子,左右端都是x,高度为h
for(int i = ; i <= n; i++)
{
scanf("%d%d%d", &tp[i].l, &tp[i].r, &tp[i].h);
}
tp[n+].l = -; tp[n+].r = N; tp[n+].h = ; //地面
sort(tp, tp+n+, cmp); //排序,为了后面可以大规模的break,节省时间
dp[][] = dp[][] = ; //初始状态
for(int i = ; i <= n+; i++)
{
dp[i][] = dp[i][] = ;
}
} void Dp()
{
for(int i = ; i <= n; i++)
{
bool p1 = , p2 = ;
for(int j = i+; j <= n+; j++) //从i上下落的j上
{
if(tp[i].h-tp[j].h > maxn) break; //如果会摔死,则进入下一块i板子。 if(tp[i].l >= tp[j].l && tp[i].l <= tp[j].r && !p1) //如果能从i的左端下落到j上
{
p1 = ; //i的左端只能下落的某一块固定板子上,无法下落到两个板子上
if(j != n+) //如果不是落到地面,则需要计算纵向位移时间和横向位移时间
{
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h+tp[i].l-tp[j].l);
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h+tp[j].r-tp[i].l);
}
else //落到地面,则不需要计算横向位移时间
{
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h);
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h);
}
}
if(tp[i].r >= tp[j].l && tp[i].r <= tp[j].r && !p2) //如果能从i的右端下落到j上
{
p2 = ; //i的右端同样只能下落的某一块固定板子上,无法下落到两个板子上
if(j != n+)
{
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h+tp[i].r-tp[j].l);
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h+tp[j].r-tp[i].r);
}
else
{
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h);
dp[j][] = min(dp[j][], dp[i][]+tp[i].h-tp[j].h);
}
}
}
}
} void output()
{
if(dp[n+][] <= m || dp[n+][] <= m) printf("NO\n");
else printf("YES\n");
} int main()
{
//freopen("test.txt", "r", stdin);
scanf("%d", &t);
while(t--)
{
init();
Dp();
output();
}
return ;
}

hdu 2155 小黑的镇魂曲(dp) 2008信息工程学院集训队——选拔赛的更多相关文章

  1. hdu2155 小黑的镇魂曲(dp)

    题意:                             小黑的镇魂曲 Problem Description 这个事情发生在某一天,当小黑和SSJ正在约会的时候,邪恶的Guner抓走了SSJ, ...

  2. 【HDOJ】2155 小黑的镇魂曲

    线段树+SPFA最短路可以过.或者DP也能过.需要注意的是xl的范围是错的,测试用例中xl可能为0,他妈的,因为这个一直莫名其妙的wa.1. spfa建图增加一倍的点即可(讨论左端点和右端点). /* ...

  3. Hdu 2157 How many ways??(DP||矩阵乘法)

    How many ways?? Time Limit:1000 MS Memory Limit: 32768 K Problem Description 春天到了, HDU校园里开满了花, 姹紫嫣红, ...

  4. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  5. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  6. hdu 2829 Lawrence(斜率优化DP)

    题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...

  7. hdu 4568 Hunter 最短路+dp

    Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  8. HDU 1231.最大连续子序列-dp+位置标记

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  9. HDU 1078 FatMouse and Cheese ( DP, DFS)

    HDU 1078 FatMouse and Cheese ( DP, DFS) 题目大意 给定一个 n * n 的矩阵, 矩阵的每个格子里都有一个值. 每次水平或垂直可以走 [1, k] 步, 从 ( ...

随机推荐

  1. HDU4612 Warm up 边双连通分量&&桥&&树直径

    题目的意思很简单,给你一个已经连通的无向图,我们知道,图上不同的边连通分量之间有一定数量的桥,题目要求的就是要你再在这个图上加一条边,使得图的桥数目减到最少. 首先要做的就是找出桥,以及每个点所各自代 ...

  2. UVA 11174 Stand in a Line (组合+除法的求模)

    题意:村子里有n个人,给出父亲和儿子的关系,有多少种方式可以把他们排成一列,使得没人会排在他父亲的前面 思路:设f[i]表示以i为根的子树有f[i]种排法,节点i的各个子树的根节点,即它的儿子为c1, ...

  3. 编写高性能JavaScript【转】

    英文链接:Writing Fast, Memory-Efficient JavaScript 很多JavaScript引擎,如Google的V8引擎(被Chrome和Node所用),是专门为需要快速执 ...

  4. Android开发--Activity生命周期回顾理解

    Activity和Servlet一样,都用了回调机制.我们通过类比servlet来学习Activity.当一个servlet开发出来之后,该servlet运行于Web服务器中.服务器何时创建servl ...

  5. Bash 小知识点

    变量定义的时候=两边不能有空格,例如: a='Hello World' 如果变量和其它字符相连,可以用{}把变量引起来,这样就可以和相连的字符隔离 除了在变量赋值和在FOR循环语句头中,BASH中的变 ...

  6. Openfire 服务端在Eclipse上部署

    http://blog.csdn.net/chexitianxia/article/details/9371169 结合: http://blog.csdn.net/ares1201/article/ ...

  7. 【nginx运维基础(3)】Nginx的编译PHP

    Apache默认是把PHP作为本身的一个模块(mod_php)来运行的,而Nginx是以FastCGI方式运行的.所以使用Nginx+PHP就是直接配置为FastCGI模式. 安装PHP 下载地址: ...

  8. Orcle数据库查询练习复习:一

    一.创建数据库和表 drop table student; create table student ( sid int, sname ), sage int, ssex ), snativeplac ...

  9. 261. Graph Valid Tree

    题目: Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nod ...

  10. 确认某端口占用情况并结束相应进程(Windows)

    (1)确认某端口是否被占用 (2)通过查找对应的PID号,定位是哪一个进程在使用该端口 (3)通过PID号结束该进程 # 查找端口2000是否被占用C:\Users\tdcqma>netstat ...