您的位置:首页 > 其它

POJ 1661 解题报告

2016-08-19 03:44 295 查看
这道题可以看做是DP也可以看成模拟。从上往下看每个平台能否到达,是否遮挡,是否到地。代码写得重复很多,应该可以简洁许多。

需要注意的地方是这里把出发点也看做了一个平台,这样按照平台高度排序的时候需要排N+1个(而不是N个)。

thestoryofsnow1661Accepted180K0MSC++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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: