POJ 1661 解题报告
2016-08-19 03:44
295 查看
这道题可以看做是DP也可以看成模拟。从上往下看每个平台能否到达,是否遮挡,是否到地。代码写得重复很多,应该可以简洁许多。
需要注意的地方是这里把出发点也看做了一个平台,这样按照平台高度排序的时候需要排N+1个(而不是N个)。
需要注意的地方是这里把出发点也看做了一个平台,这样按照平台高度排序的时候需要排N+1个(而不是N个)。
thestoryofsnow | 1661 | Accepted | 180K | 0MS | C++ | 3018B |
/* ID: thestor1 LANG: C++ TASK: poj1661 */ #include <iostream> #include <fstream> #include <cmath> #include <cstdio> #include <cstring> #include <limits> #include <string> #include <vector> #include <list> #include <set> #include <map> #include <queue> #include <stack> #include <algorithm> #include <cassert> using namespace std; const int MAXN = 1000 + 1; const int INF = 40000000; class Platform { public: int x1, x2, y; Platform() {} Platform(int x1, int x2, int y) : x1(x1), x2(x2), y(y) {} inline bool operator< (const Platform& rhs) const { return this->y > rhs.y; } }; bool covered(int x11, int x21, int x12, int x22) { if (x12 >= x21 || x22 <= x11) { return false; } return true; } int main() { int T; scanf("%d", &T); Platform platforms[MAXN]; // DP[i][0] records the minimal time to reach the left end of platforms[i] from (X, Y) // DP[i][1] is for the right end int DP[MAXN][2]; int N, X, Y, MAX; for (int t = 0; t < T; ++t) { scanf("%d%d%d%d", &N, &X, &Y, &MAX); platforms[0].x1 = X; platforms[0].x2 = X; platforms[0].y = Y; for (int i = 1; i <= N; ++i) { scanf("%d%d%d", &platforms[i].x1, &platforms[i].x2, &platforms[i].y); } sort(platforms, platforms + N + 1); // printf("[debug]platforms:\n"); // for (int i = 0; i <= N; ++i) { // printf("%d %d %d\n", platforms[i].x1, platforms[i].x2, platforms[i].y); // } DP[0][0] = DP[0][1] = 0; for (int i = 1; i <= N; ++i) { DP[i][0] = DP[i][1] = INF; } int ans = INF; for (int i = 0; i <= N; ++i) { bool leftUncovered = true; for (int j = i + 1; j <= N && platforms[j].y >= platforms[i].y - MAX; ++j) { if (platforms[j].x1 <= platforms[i].x1 && platforms[i].x1 <= platforms[j].x2) { DP[j][0] = min(DP[j][0], DP[i][0] + (platforms[i].y - platforms[j].y) + abs(platforms[j].x1 - platforms[i].x1)); DP[j][1] = min(DP[j][1], DP[i][0] + (platforms[i].y - platforms[j].y) + abs(platforms[j].x2 - platforms[i].x1)); leftUncovered = false; break; } } // if the left side of platforms[i] can fall to ground (y == 0) if (leftUncovered && platforms[i].y - MAX <= 0) { ans = min(ans, DP[i][0] + platforms[i].y); } bool rightUncovered = true; for (int j = i + 1; j <= N && platforms[j].y >= platforms[i].y - MAX; ++j) { if (platforms[j].x1 <= platforms[i].x2 && platforms[i].x2 <= platforms[j].x2) { DP[j][0] = min(DP[j][0], DP[i][1] + (platforms[i].y - platforms[j].y) + abs(platforms[j].x1 - platforms[i].x2)); DP[j][1] = min(DP[j][1], DP[i][1] + (platforms[i].y - platforms[j].y) + abs(platforms[j].x2 - platforms[i].x2)); rightUncovered = false; break; } } // if the right side of platforms[i] can fall to ground (y == 0) if (rightUncovered && platforms[i].y - MAX <= 0) { ans = min(ans, DP[i][1] + platforms[i].y); } } // printf("[debug]DP:\n"); // for (int i = 0; i <= N; ++i) { // printf("DP[%d]: %d, %d\n", i, DP[i][0], DP[i][1]); // } printf("%d\n", ans); } return 0; }
相关文章推荐
- POJ 1661 帮助Jimmy 解题报告
- POJ 2000 解题报告
- poj 3617 Best Cow Line 解题报告
- POJ 3295 Tautology解题报告
- [解题报告]POJ-2698-八皇后问题
- POJ 2528 解题报告
- poj2498解题报告
- POJ-1067 取石子游戏 解题报告
- poj解题报告——2115
- 【不严谨的NEXT函数陷阱】poj 1961——Period解题报告及反例一组
- POJ 2977 生理周期 解题报告
- POJ 3083 Children of the Candy Corn 解题报告
- POJ 1005 解题报告 I Think I Need a Houseboat
- POJ - 3264 Balanced Lineup解题报告(RMQ问题 ST算法 魔板题)
- poj 3774 Elune’s Arrow 解题报告
- POJ 2446解题报告
- POJ 1013 解题报告
- poj分类解题报告索引
- poj2126解题报告
- POJ 3126 Prime Path 解题报告(BFS & 双向BFS)