感觉蛮坑的一道题。

题意很像一个叫“是男人下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. C#中sealed关键字

    C#中sealed关键字 1. sealed关键字     当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承.类似于Java中final关键字.     在下面的示例中,类 B ...

  2. POJ 3270 Cow Sorting(置换群)

    题目链接 题意 : N头牛,每个牛的坏脾气都有一个值,每个值都不相同,把这个值按照从小到大排序,如果两个值交换,那么会花掉这两个值之和的时间,让你花最少的时间将每个值从小到大排好序,求最小的总时间. ...

  3. Android 父类super.onDestroy();的有关问题

    super.onDestroy(); 的问题. 注意:没有显式地在自己的方法中调用父类Activity的onDestroy是会报错的.我的问题很简单,在我覆盖的onDestroy(),方法中需要调用父 ...

  4. 使用getScript()方法异步加载并执行js文件

    使用getScript()方法异步加载并执行js文件 使用getScript()方法异步请求并执行服务器中的JavaScript格式的文件,它的调用格式如下所示: jQuery.getScript(u ...

  5. mvn 安装ojdbc6.jar

    mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion= - Dpackaging=jar -Dfile ...

  6. PX(计算机语言中的像素)

    PX是Pixel的缩写, 也就是说像素是指基本原色素及其灰度的基本编码, 由 Picture(图像) 和 Element(元素)这两个单词的字母所组成的,如同摄影的相片一样,数码影像也具有连续性的浓淡 ...

  7. Linux Shell脚本入门:tee命令

    用途说明   在执行Linux命令时,我们可以把输出重定向到文件中,比如 ls >a.txt,这时我们就不能看到输出了,如果我们既想把输出保存到文件中,又想在屏幕上看到输出内容,就可以使用tee ...

  8. Tomcat的SessionID引起的Session Fixation和Session Hijacking问题

    上一篇说到<Spring MVC防御CSRF.XSS和SQL注入攻击>,今天说说SessionID带来的漏洞攻击问题.首先,什么是Session Fixation攻击和Session Hi ...

  9. json-lib 中关于null与"null"

    总感觉json-lib里面关于null和"null"的处理非常不合理,或者说是bug,去了json-lib的网站,最后一次更新是10年了... 发现官方网站第一段就说json-li ...

  10. AXURE制作APP抽屉式菜单

    1.拖一个dynamic panel到窗体,将State1改名为State_首页: 2.拖2个dynamic panel到State_首页中,分别命名为侧边菜单及首页内容,首页内容盖住侧边菜单: 3. ...