看了别人的博客才AC的。
这题以dp为主要,线段树打辅助,线段树为后面的dp做铺垫!
首先想怎么dp:
1、建立一个结构体
struct plank{
int h , l , r, value;//木板本身的属性,高度、左端点、右端点、值
int vl , vr; //从木板左边跳到vl木板 , 右边跳到vr木板
plank(int H = 0, int L = 0, int R = 0,int V = 0){
h = H , l = L , r = R ,value = V;
}
};
2、把木板按照高度从低到高排序
3、状态转移方程,很好理解,看看就能懂
for(int i = N;i >=1;i--){
dp[p[i].vl] = max(dp[p[i].vl] ,dp[i]+p[p[i].vl].value);
dp[p[i].vr] = max(dp[p[i].vr] ,dp[i]+p[p[i].vr].value);
}
然后,想求出plank中的vl、vr,就用线段树!
1、
struct tree{
int l , r , id;//id指l到r区间,第几块木板,初始化为0,我们木板的编号从1开始,0表示地板;
}a[4*maxn];
4
5 2 4 100 //plank4
4 1 3 100 //plank3
3 3 4 100 //plank2
2 1 4 100 //plank1
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 100010;
struct plank{
int h , l , r, value;
int vl , vr;
plank(int H = 0, int L = 0, int R = 0, int V = 0){
h = H , l = L , r = R , value = V;
}
}p[maxn];
struct tree{
int l , r , id;
}a[4*maxn];
int N , dp[maxn];
bool cmp(plank p1 , plank p2){
return p1.h < p2.h;
}
void pushdown(int k){
if(a[k].l != a[k].r){
a[2*k].id = a[k].id;
a[2*k+1].id = a[k].id;
a[k].id = -1;
}
}
void build(int l , int r , int k){
a[k].l = l;
a[k].r = r;
a[k].id = 0;
if(l != r){
int mid = (l+r)/2;
build(l , mid , 2*k);
build(mid+1 , r , 2*k+1);
}
}
int query(int k , int x){
if(a[k].id != -1){
return a[k].id;
}else{
int mid = (a[k].l+a[k].r)/2;
if(mid >= x){
return query(2*k , x);
}else{
return query(2*k+1 , x);
}
}
}
void add(int l , int r , int k, int id){
if(l <= a[k].l && a[k].r <= r){
a[k].id = id;
}else{
if(a[k].id != -1){
pushdown(k);
}
int mid = (a[k].l+a[k].r)/2;
if(mid >= r){
add(l , r , 2*k , id);
}else if(mid < l){
add(l , r , 2*k+1 , id);
}else{
add(l , mid , 2*k , id);
add(mid+1 , r , 2*k+1 , id);
}
}
}
void initial(){
for(int i = 0;i < maxn;i++){
dp[i] = 0;
p[i].value = 0;
}
}
void readcase(){
int h , xl , xr , v , M_r = 0;
for(int i = 1;i <= N;i++){
scanf("%d%d%d%d" , &h , &xl , &xr , &v);
p[i] = plank(h , xl ,xr , v);
M_r = max(M_r , xr);
}
build(1 , M_r , 1);
}
void computing(){
sort(p+1 , p+N+1 , cmp);
for(int i = 1;i <= N;i++){
p[i].vl = query(1 , p[i].l);
p[i].vr = query(1 , p[i].r);
add(p[i].l , p[i].r , 1 , i);
//cout << i << ":" << p[i].vl << " " << p[i].vr << endl;
}
dp[N] = p[N].value+100;
for(int i = N;i >= 1;i--){
dp[p[i].vl] = max(dp[p[i].vl] , dp[i]+p[p[i].vl].value);
dp[p[i].vr] = max(dp[p[i].vr] , dp[i]+p[p[i].vr].value);
//cout << dp[i] << ":" << p[i].vl <<"=" << dp[p[i].vl] << " " <<p[i].vr <<"=" << dp[p[i].vr]<<endl;
}
if(dp[0]>0){
cout << dp[0] << endl;
}else{
cout << -1 << endl;
}
}
int main(){
while(cin >> N){
initial();
readcase();
computing();
}
return 0;
}