Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 7549 | Accepted: 2405 |
Description
Input
Output
Sample Input
1 3 8 17 20 0 10 8 0 10 13 4 14 3
Sample Output
23Jimmy 跳到一块板上后,可以有两种选择,向左走,或向右走。走到左端和走到右端所需的时间,是很容易算的。如果我们能知道,以左端为起点到达地面的最短时间,和以右端为起点到达地面的最短时间,那么向左走还是向右走,就很容选择了。因此,整个问题就被分解成两个子问题,即Jimmy 所在位置下方第一块板左端为起点到地面的最短时间,和右端为起点到地面的最短时间。这两个子问题在形式上和原问题是完全一致的。将板子从上到下从1 开始进行无重复的编号(越高的板子编号越小,高度相同的几块板子,哪块编号在前无所谓),那么,和上面两个子问题相关的变量就只有板子的编号,所以,本题目的“状态”就是板子编号,而一个“状态”对应的“值”有两部分,是两个子问题的解,即从该板子左端出发到达地面的最短时间,和从该板子右端出发到达地面的最短时间。不妨认为Jimmy 开始的位置是一个编号为0,长度为0 的板子,假设LeftMinTime(k)表示从k 号板子左端到地面的最短时间,RightMinTime(k)表示从k 号板子右端到地面的最短时间,那么,求板子k 左端点到地面的最短时间的方法如下:
point坐标写错N个,WA N次。没有注意从起点直接下落,wa。。。
为爱debug,期末要挂科。。。
代码:
#include <iostream> #include <cstring> #include <algorithm> using namespace std; const int MAX = 999999; struct Point{ int x; int y; int height; }point[1005]; bool cmp(Point a, Point b) { return a.height < b.height; } int dp[1005][1005]; int n, num; void MinTime() { int next_x, next_y; bool flag_x, flag_y; dp[1][point[1].x] = point[1].height; dp[1][point[1].y] = point[1].height; for(int i = 2; i <= n + 1; i++) { flag_x = false; for(int j = i - 1; j >= 1; j--) { if(point[j].x <= point[i].x && point[i].x <= point[j].y) { next_x = j; flag_x = true; break; } } if(flag_x) { if(point[i].height - point[next_x].height <= num) //注意中途也要考虑小于最大下降高度,摔死老鼠怎么办? dp[i][point[i].x] = point[i].height - point[next_x].height + min(dp[next_x][point[next_x].x]+point[i].x-point[next_x].x,dp[next_x][point[next_x].y]+point[next_x].y-point[i].x); else dp[i][point[i].x] = MAX; } else { if(point[i].height > num) dp[i][point[i].x] = MAX; else dp[i][point[i].x] = point[i].height; } flag_y = false; for(int j = i - 1; j >= 1; j--) { if(point[j].y >= point[i].y && point[i].y >= point[j].x) { next_y = j; flag_y = true; break; } } if(flag_y) { if(point[i].height - point[next_y].height <= num) dp[i][point[i].y] = point[i].height - point[next_y].height + min(dp[next_y][point[next_y].x]+point[i].y-point[next_y].x,dp[next_y][point[next_y].y]+point[next_y].y-point[i].y); else dp[i][point[i].y] = MAX; } else { if(point[i].height > num) { dp[i][point[i].y] = MAX; } else { dp[i][point[i].y] = point[i].height; } } } } int main() { freopen("in.txt","r",stdin); int t, x, y, i; cin >> t; while(t--) { memset(dp, 0, sizeof(dp)); memset(point, 0, sizeof(point)); cin >> n >> x >> y >> num; for(i = 1; i <= n; i++) { cin >> point[i].x >> point[i].y >> point[i].height; } point[n+1].x = point[n+1].y = x; point[n+1].height = y; sort(point + 1, point + n + 2, cmp); MinTime(); cout<<dp[n+1][point[n+1].x]<<endl; } return 0; }