Help Jimmy

POJ - 1661

题意:大致是一个人从某个点开始下落,下落的速度是1m/s,然后在平台上的时候可以左右移动,移动的速度也是1m/s,但是这里有一个限制,就是说每次下落的距离不能超过一个给定的数值。问你从起始点下落到地板最少需要多少s。

题解,这道题我看到的时候第一感觉是最短路,建图方法就是对于每一个平台的两个端点(编号为2*i+1和2*i+2),考虑这个从端点所能下落到的下一个平台的两个端点,比如,根据上一个平台的某个端点到下一个最近的平台的两个端点所需要的时间来建立边(边权就是耗费的时间)

最后别忘了从起点开始的建边以及端点到地板的建边!

动态规划的做法等会了再补上

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
#define int long long
const int MAXN = 2005;
const int INF = 1e18;
int N,X,Y,MAX;
//int G[MAXN][MAXN];
//vector<int> G[MAXN];
int head[MAXN];
struct edge{int v;int next;int cost;
}Es[MAXN<<1];
int d[MAXN];
int cnt;
typedef pair<int,int> P;
struct node{int x1,x2,h;friend bool operator<(node n1,node n2){return n1.h > n2.h;}
};
node ns[MAXN];
void dijkstra(int x){for(int i = 0;i <= MAXN;i++)d[i] = INF;d[x] = 0;priority_queue<P,vector<P>,greater<P> > que;que.push(P(0,x));while(!que.empty()){P p = que.top();que.pop();int dis = p.first;int v = p.second;if(d[v] < dis) continue;//for(int i = 0;i < 2*N+2;i++){for(int e = head[v];e!= -1;e = Es[e].next){int cost = Es[e].cost;int i = Es[e].v;if(cost + d[v] < d[i]){d[i] = d[v] + cost;que.push(P(d[i],i));}}}
}
inline void add_edge(int i,int j,int cost){//G[i][j] = cost;Es[cnt].v = j;Es[cnt].cost = cost;Es[cnt].next = head[i];head[i] = cnt++;
}
void init(){cnt = 0;memset(head,-1,sizeof(head));
}
main(){int t;scanf("%lld",&t);while(t--){init();scanf("%lld%lld%lld%lld",&N,&X,&Y,&MAX);for(int i = 0;i < N;i++){int x1,x2,h;scanf("%lld%lld%lld",&x1,&x2,&h);ns[i].x1 = x1;ns[i].x2 = x2;ns[i].h = h;}sort(ns,ns+N);//create graphfor(int i = 0;i < N;i++){int l = 0,r = 0;int f = 1;for(int j = i + 1;j < N;j++){if(ns[i].h - ns[j].h > MAX){f = 0;break;}if(!l && ns[i].x1 >= ns[j].x1 && ns[i].x1 <= ns[j].x2){l = 1;add_edge(2*i+1,2*j+1,ns[i].h - ns[j].h + ns[i].x1 - ns[j].x1);add_edge(2*i+1,2*j+2 ,ns[i].h - ns[j].h + ns[j].x2 - ns[i].x1);}if(!r && ns[i].x2 >= ns[j].x1 && ns[i].x2 <= ns[j].x2){r = 1;add_edge(2*i+2,2*j+1,ns[i].h - ns[j].h + ns[i].x2 - ns[j].x1);add_edge(2*i+2,2*j+2,ns[i].h - ns[j].h + ns[j].x2 - ns[i].x2);}if(r && l) break;}if(!f)continue; if(!l && ns[i].h <= MAX){add_edge(2*i+1,2*N+1,ns[i].h);}if(!r && ns[i].h <= MAX){add_edge(2*i+2,2*N+1,ns[i].h);}}int f = 0;for(int i = 0;i < N;i++){if(X > ns[i].x1 && X < ns[i].x2 && Y >= ns[i].h && Y - ns[i].h <= MAX){add_edge(0,2*i+1,Y - ns[i].h + X - ns[i].x1);add_edge(0,2*i+2,Y - ns[i].h + ns[i].x2 - X);f = 1;break;}}if(!f){if(Y <= MAX){add_edge(0,2*N+1,Y);}}dijkstra(0);cout<<d[2*N+1]<<endl;}
}

动态规划训练19、最短路 [Help Jimmy POJ - 1661 ]相关推荐

  1. Help Jimmy POJ - 1661

    Help Jimmy POJ - 1661 题意: 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终 ...

  2. 动态规划训练20 [Treats for the Cows POJ - 3186 ]

    Treats for the Cows POJ - 3186 简单的区间DP,就不解释了. #include<iostream> #include<cstdio> using ...

  3. POJ 1661 Help Jimmy(递推DP)

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

  4. 动态规划训练23 [Making the Grade POJ - 3666 ]

    Making the Grade POJ - 3666 这道题目有点意思. 我们定义dp[i][j]表示的含义是把包含前i个元素的子序列变成非递减的子序列,并且最后一个元素变成j所需要耗费的最小代价 ...

  5. 动态规划训练22 [Milking Time POJ - 3616 ]

    Milking Time POJ - 3616 说实话这道题目非常简单,本质上就是 多段有向图的求最大值问题.稍微变化的地方在于这个的的有向边没有那么明显 ,而是需要自己去寻找 如果任务i到任务j之间 ...

  6. 动态规划训练9 [Brackets POJ - 2955 ]

    Brackets POJ - 2955 再明显不过的区间DP的题目了,要求求出给出符号式中最大匹配的括号数. 考虑区间[l,r],如果str[l]与str[r]匹配了,那么转移方程为dp[l][r] ...

  7. 动态规划训练13 [Catch That Cow poj3278]

    Catch That Cow POJ - 3278 这道题我看大家用的方法都是bfs搜索,为什么在我看来这就是一个动态规划的题目啊啊啊啊啊啊啊 dp[x]表示从N出发到x所需要的最小时间 那么得到如下 ...

  8. Vijos 1404 遭遇战 - 动态规划 - 线段树 - 最短路 - 堆

    背景 你知道吗,SQ Class的人都很喜欢打CS.(不知道CS是什么的人不用参加这次比赛). 描述 今天,他们在打一张叫DUSTII的地图,万恶的恐怖分子要炸掉藏在A区的SQC论坛服务器!我们SQC ...

  9. POJ 1661 Help Jimmy

    传送门:http://poj.org/problem?id=1661 解题思路:其实吧,不难就是细节有点麻烦. 实现代码: #include <iostream> #include < ...

最新文章

  1. 《JavaScript框架设计》——1.3 数组化
  2. Mysql insert语句的优化
  3. 第四次测试--面向对象
  4. P4718 【模板】Pollard-Rho算法
  5. 操作系统中的page cache机制
  6. arm开发板上找不到/dev/i2c-*设备
  7. async/await 异步编程(转载)
  8. cad2019菜单栏怎么调出来_AutoCAD2019工具栏如何调出?工具栏调出方法图文推荐
  9. Windows驱动编程基础(下)之电源管理
  10. iptables实现网卡包的转发
  11. Excel 入门基础
  12. 图灵 数理逻辑 人工智能 图灵机与计算问题 论文
  13. linux用户自动输入密码,Linux自动输入密码登录用户
  14. c++英雄联盟_C联盟
  15. transform:translate
  16. java并行编程_RxJava(十一): 并行编程
  17. RSA加密与解密(Java实现)
  18. 超融合一体机与软件选哪个好?适合什么场景?各有什么利弊?
  19. S5P4418:RTC芯片HYM8563驱动移植
  20. 禁用计算机账户控制,禁用当前的账户【应对步骤】

热门文章

  1. 算法设计与分析——动态规划——矩阵连乘问题
  2. JAVA实验报告九异常处理_Java课后练习9(异常处理)
  3. 《C++ Primer》13.1.3节练习
  4. 最短路弗洛伊德(Floyd)算法加保存路径
  5. P2371 [国家集训队]墨墨的等式 同余最短路
  6. CF1526 D. Kill Anton
  7. [2020-11-30 contest]数列(矩阵加速),秘密通道(dijkstra最短路)小X游世界树(换根dp),划分(数学)
  8. 2021 NOI游记
  9. 不止代码:友好城市(动态规划)
  10. CF1553H-XOR and Distance【dp】