# Man Down solution report (hdu3016 dynamic programming line tree sorting)

Http://acm.hdu.edu.cn/showproblem.php? Pid=3016

## Algorithm design

To get the question, let's talk about the wooden boards according to their height, and then increase the number of them from bottom to top from 1. (we think the bottom floor number is 0). Through such a step, it is obvious that the higher the number of wooden boards is, the larger the number is.

According to the meaning, if a man is on a wooden plank, he can only drop vertically from the left or right side of the plank. We define d[i] as the maximum life value when this person reaches the I plate. If we know the value of d[i], we can introduce the corresponding value of the board on the left or right side. (d[j] = d[i] + jump to the change of the value of life on the j board). In this way, we can solve recursively from top to bottom.

But how do we know where he falls on the left or right side? We can set up a segment tree for the X axis according to the point, and then from bottom to top, according to the "X" dyeing of the board (that is, the place mark on the board covered by the board), in the process of pushing upward, it is very convenient to find out which board will jump on the left and right side of the board.

## Sample code

`````` #include <cstdio>
#include <cstring>
#include <algorithm>

const int N = 110000, L = 110000, INF = 0x7fffffff;

int n;

struct a_d {
int h, l, r, v;
int ld, rd; // left down to
} a[N];

inline bool cmp(a_d a, a_d b) {
return a.h < b.h;
}

struct node {
int l, r;
int f;
node *lc, *rc;
} mem[2 * L];
node *memp;
node *root;

node *init(int l, int r) {
node *p = memp++;
p->l = l;
p->r = r;
p->f = 0;
if (l == r) {
p->lc = p->rc = NULL;
} else {
int mid = (l + r) >> 1;
p->lc = init(l, mid);
p->rc = init(mid + 1, r);
}
return p;
}

inline void push_down(node *p) {
if (p->f) {
p->lc->f = p->f;
p->rc->f = p->f;
p->f = 0;
}
}

void change(node *p, int l, int r, int f) {
if (l <= p->l && p->r <= r) {
p->f = f;
return;
}

push_down(p);
int mid = (p->l + p->r) >> 1;
if (l <= mid) change(p->lc, l, r, f);
if (mid < r) change(p->rc, l, r, f);
}

int query(node *p,  int i) {
if (i == p->l && p->r == i) {
return p->f;
}

push_down(p);
int mid = (p->l + p->r) >> 1;
if (i <= mid) return query(p->lc, i);
return query(p->rc, i);
}

int d[N];

inline int max(int a, int b) {
if (a > b) return a; else return b;
}

int main() {
//  freopen("input.txt", "r", stdin);

while(scanf("%d", &n) != EOF) {
for (int i = 1; i <= n; ++i) scanf("%d%d%d%d", &a[i].h, &a[i].l, &a[i].r, &a[i].v);
a[0].v = 0;

std::sort(a + 1, a + n + 1, cmp);
//
//      for (int i = 1; i <= n; ++i) printf("%d %d %d\n", i, a[i].l, a[i].r); printf("\n");

memp = mem;
root = init(0, 100010);
for (int i = 1; i <= n; ++i) {
//          printf("%d %d %d\n", i, a[i].l, a[i].r);
a[i].ld = query(root, a[i].l); // 注意这里不 +1 -1
a[i].rd = query(root, a[i].r);
change(root, a[i].l, a[i].r, i);
}
//
//      for (int i = 1; i <= n; ++i) printf("%d %d %d\n", i, a[i].ld, a[i].r D);

for (int i = 0; I < = n; ++i) d[i] = -INF;
d[n] = 100 + a[n].v; -INF (= =; (int) = (0)); (= = ((), + +); = = (=, (+, + +)); ((0)} ("" ",") ";"``````

This site uses Akismet to reduce spam reviews. Learn how we process your comment data.