HDU 3016 Man Down
题意:是男人就下100层的游戏的简单版,每次仅仅能从两端下落。求落地最大血量
思路:利用线段树能够处理出每一个线段能来自哪几个线段。然后就是dag最长路了
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std; const int N = 100005; int n; struct Line {
int l, r, y, val;
Line() {}
Line(int l, int r, int y, int val) {
this->l = l; this->r = r;
this->y = y; this->val = val;
}
void read() {
scanf("%d%d%d%d", &y, &l, &r, &val);
}
} line[N]; bool cmp(Line a, Line b) {
return a.y < b.y;
} #define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2) struct Node {
int l, r, id, lazy;
void gao(int v) {
lazy = v;
id = v;
}
} node[4 * N]; void build(int l, int r, int x = 0) {
node[x].l = l; node[x].r = r;
node[x].id = node[x].lazy = -1;
if (l == r) return;
int mid = (l + r) / 2;
build(l, mid, lson(x));
build(mid + 1, r, rson(x));
} void pushdown(int x) {
if (node[x].lazy != -1) {
node[lson(x)].gao(node[x].lazy);
node[rson(x)].gao(node[x].lazy);
node[x].lazy = -1;
}
} void add(int l, int r, int v, int x = 0) {
if (node[x].l >= l && node[x].r <= r) {
node[x].gao(v);
return;
}
pushdown(x);
int mid = (node[x].l + node[x].r) / 2;
if (l <= mid) add(l, r, v, lson(x));
if (r > mid) add(l, r, v, rson(x));
} int query(int v, int x = 0) {
if (node[x].l == node[x].r) return node[x].id;
int mid = (node[x].l + node[x].r) / 2;
pushdown(x);
if (v <= mid) return query(v, lson(x));
if (v > mid) return query(v, rson(x));
} const int INF = 0x3f3f3f3f; int dp[N]; vector<int> g[N]; int main() {
while (~scanf("%d", &n)) {
build(0, 100000);
line[n] = Line(0, 100000, 0, 0);
for (int i = 0; i < n; i++) {
line[i].read();
g[i].clear();
}
n++;
sort(line, line + n, cmp);
for (int i = 0; i < n; i++) {
if (i) {
int tol = query(line[i].l);
int tor = query(line[i].r);
g[tol].push_back(i);
if (tol != tor)
g[tor].push_back(i);
}
add(line[i].l, line[i].r, i);
}
line[n - 1].val += 100;
dp[n - 1] = line[n - 1].val;
for (int i = n - 2; i >= 0; i--) {
dp[i] = -INF;
for (int j = 0; j < g[i].size(); j++)
dp[i] = max(dp[i], dp[g[i][j]] + line[i].val);
}
if (dp[0] <= 0) dp[0] = -1;
printf("%d\n", dp[0]);
}
return 0;
}