这题太坑人了,虽说是线段树+dp,可是这道题的题意确实不明确,你要知道,要想从高的木板下落到低的木板上面,假设高的木板的区间为[l, r],那么你只能从点
l和点r也就是这条木板的两个端点下去,而不是从l - 1和r + 1这两个点下去(就是坑在这,让我无数次的wa);唉……这该怎么说呢。
说一下自己的思路:按照高度进行排序,高度递减,首先查找区间[l, r]中的最大值,把这个最大值记录下来,把区间[l + 1, r - 1]赋为负数(或者其他<= 0 的数都可以), 把记录下来的数加在当前
木板的权值上面,就会得到在这条木板上的最大值;当然在区间[l, r]中也会查找到出现<= 0 的数,这时候就不要在更显区间了,因为这时候已经死在上一条木板上面了。
注意:刚开始的木板如果权值+100 <= 0这时候就不需要进行其他操作了,直接输出-1就可以了
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>
#define INF 0x3fffffff
#define inf -0x3f3f3f3f
#define N 100010
#define M (N << 2)
#define LL long long
#define mod 95041567
using namespace std;
struct Node {
int h;
int MAX;
};
struct Interval{
int h;
int l;
int r;
int val;
bool operator < (const Interval &p) const{
return h > p.h;
}
};
Interval arr[N];
Node tree[M];
void build(int rt, int l, int r){
int mid = ((r - l) >> 1) + l;
int lc = rt << 1;
int rc = lc | 1;
tree[rt].MAX = -1;
tree[rt].h = 0;
if(l == r) return;
build(lc, l, mid);
build(rc, mid + 1, r);
}
void pushdown(int rt, int lc, int rc){
if(tree[rt].h) return ;
tree[lc] = tree[rc] = tree[rt];
}
void pushup(int rt, int lc, int rc){
tree[rt].h = -1;
if(tree[lc].h == tree[rc].h && ! tree[lc].h) tree[rt].h = 0;
tree[rt].MAX = max(tree[lc].MAX, tree[rc].MAX);
}
void update_node(int rt, int l, int r, int pos, int val){
int mid = ((r - l) >> 1) + l;
int lc = rt << 1;
int rc = lc | 1;
if(r == l) {
tree[rt].MAX = val;
tree[rt].h = 1;
return ;
}
pushdown(rt, lc, rc);
if(pos > mid) update_node(rc, mid + 1, r, pos, val);
else update_node(lc, l, mid, pos, val);
pushup(rt, lc, rc);
}
void update_interval(int rt, int l, int r, int L, int R){
int mid = ((r - l) >> 1) + l;
int lc = rt << 1;
int rc = lc | 1;
if(l == L && r == R) {
tree[rt].h = 0;
tree[rt].MAX = -1;
return ;
}
pushdown(rt, lc, rc);
if(L > mid) update_interval(rc, mid + 1, r, L, R);
else if(R <= mid) update_interval(lc, l, mid, L, R);
else {
update_interval(lc, l, mid, L, mid);
update_interval(rc, mid + 1, r, mid + 1, R);
}
pushup(rt, lc, rc);
}
int query(int rt, int l, int r, int L, int R) {
int mid = ((r - l) >> 1) + l;
int lc = rt << 1;
int rc = lc | 1;
if(l == L && r == R) return tree[rt].MAX;
pushdown(rt, lc, rc);
int val;
if(L > mid) val = query(rc, mid + 1, r, L, R);
else if(R <= mid) val = query(lc, l, mid, L, R);
else val = max(query(lc, l, mid, L, mid), query(rc, mid + 1, r, mid + 1, R));
pushup(rt, lc, rc);
return val;
}
int main() {
//freopen("in.txt", "r", stdin);
int n;
while(scanf("%d", &n) != EOF){
int l = INF, r = 0;
for(int i = 0; i < n; ++ i){
scanf("%d %d %d %d", &arr[i].h, &arr[i].l, &arr[i].r ,&arr[i].val);
l = min(l, arr[i].l);
r = max(r, arr[i].r);
}
build(1, l, r);
sort(arr, arr + n);
arr[0].val += 100;
if(arr[0].val <= 0) {
puts("-1");
continue ;
}
update_node(1, l, r, arr[0].l, arr[0].val);
update_node(1, l, r, arr[0].r, arr[0].val);
for(int i = 1; i < n; ++ i) {
int val = query(1, l, r, arr[i].l, arr[i].r);
if(val <= 0) continue ;
val += arr[i].val;
if(arr[i].r - arr[i].l >= 2) update_interval(1, l, r, arr[i].l + 1, arr[i].r - 1);
update_node(1, l, r, arr[i].l, val);
update_node(1, l, r, arr[i].r, val);
}
int val = tree[1].MAX;
if(val > 0) printf("%d\n", val);
else puts("-1");
}
return 0;
}
hdu 3016 Man Down
最新推荐文章于 2020-12-15 16:07:31 发布