hdu 2155 小黑的镇魂曲(dp) 2008信息工程学院集训队——选拔赛
感觉蛮坑的一道题。
题意很像一个叫“是男人下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信息工程学院集训队——选拔赛的更多相关文章
- hdu2155 小黑的镇魂曲(dp)
题意: 小黑的镇魂曲 Problem Description 这个事情发生在某一天,当小黑和SSJ正在约会的时候,邪恶的Guner抓走了SSJ, ...
- 【HDOJ】2155 小黑的镇魂曲
线段树+SPFA最短路可以过.或者DP也能过.需要注意的是xl的范围是错的,测试用例中xl可能为0,他妈的,因为这个一直莫名其妙的wa.1. spfa建图增加一倍的点即可(讨论左端点和右端点). /* ...
- Hdu 2157 How many ways??(DP||矩阵乘法)
How many ways?? Time Limit:1000 MS Memory Limit: 32768 K Problem Description 春天到了, HDU校园里开满了花, 姹紫嫣红, ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- hdu 5094 Maze 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...
- hdu 2829 Lawrence(斜率优化DP)
题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...
- hdu 4568 Hunter 最短路+dp
Hunter Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
- HDU 1231.最大连续子序列-dp+位置标记
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- HDU 1078 FatMouse and Cheese ( DP, DFS)
HDU 1078 FatMouse and Cheese ( DP, DFS) 题目大意 给定一个 n * n 的矩阵, 矩阵的每个格子里都有一个值. 每次水平或垂直可以走 [1, k] 步, 从 ( ...
随机推荐
- Chp18: Hard
18.1 Write a function that adds two numbers. You should not use + or any arithmetic operators. Solut ...
- aChartEngine图表显示
android的数据报表显示 从图中,我们可以看出,绘制一个图表我们其实,我们只需要理解三个概念 1,ChartFactory ,传入XYMutilpleSeriesRenderer,XYMutilp ...
- hdu 1709 The Balance
母函数的特殊情况,左右两边都可以放,如样例1,2,9 母函数为(1+x+1/x)*(1+x^2+1/x^2)*(1+x^9+1/x^9) 化简为(1+x+x^2)*(1+x^2+x^4)*(1+x^9 ...
- C# 计算一段代码执行的时间函数
使用 Stopwatch 类 eg: 计算一个for循环需要的时间 Stopwatch watch = new Stopwatch(); watch.Start(); ; i < ; i++) ...
- java 追加写入代码一例
最近最项目参数化的时候用到,场景是这样的,需要测试A和B两个接口,其中B接口传入的参数必须是传递给A接口过的,所以整理一个思路就是: 1. 正常调用A接口,但是将传递给A接口的参数保存到文本里,此处要 ...
- [主席树]SPOJ DQUERY
题目链接 题意:n个数 m个查询 查询的是[l, r]区间内不相同的数的个数 没有修改,因此静态的主席树就好了 将重复的元素建树即可 query的时候加起来,用区间长度(r-l+1)去减就是答案 (q ...
- lintcode 中等题:digits counts 统计数字
题目 统计数字 计算数字k在0到n中的出现的次数,k可能是0~9的一个值 样例 例如n=12,k=1,在 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],我们发现 ...
- 对cost函数的概率解释
Likehood函数即似然函数,是概率统计中经常用到的一种函数,其原理网上很容易找到,这里就不讲了.这篇博文主要讲解Likelihood对回归模型的Probabilistic interpretati ...
- iOS开发 -- 发送JSON数据给服务器
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // 1.URL NSURL *url = [NSURL URLW ...
- Orcle数据库查询练习复习:四
一.题目 1.找出张三的最高分和最低分以及对应的课程名 select * from course c,mark m where c.cid=m.cid and sid =(select sid fro ...