对每一个木板,用线段树去找它左边和右边能到达到的木板的编号:
最后dp:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct p { int l; int r; int n; int mark; } tree[444444]; struct pp { int ln; int rn; int l; int r; int v; int h; } s[111111]; void build(int n,int l,int r) { tree[n].l = l; tree[n].r = r; tree[n].mark =0; tree[n].n = -1; if(l == r) return ; int mid = (l+r)/2; build(n*2,l,mid); build(n*2+1,mid+1,r); } void update(int n,int l,int r,int k) { if(tree[n].l == l&&tree[n].r == r) { tree[n].mark = 1; tree[n].n = k; return ; } int mid = (tree[n].l + tree[n].r)/2; if(tree[n].mark!=0) { tree[n*2].mark = tree[n*2+1].mark = tree[n].mark; tree[n*2].n = tree[n*2+1].n = tree[n].n; tree[n].mark=0; } if(r<=mid) { update(n*2,l,r,k); } else if(l>mid) { update(n*2+1,l,r,k); } else { update(n*2,l,mid,k); update(n*2+1,mid+1,r,k); } } int query(int n,int x) { if(tree[n].l == tree[n].r) return tree[n].n; int mid=(tree[n].l+tree[n].r)/2; if(tree[n].mark==1) { tree[n*2].mark = tree[n*2+1].mark = tree[n].mark; tree[n*2].n = tree[n*2+1].n = tree[n].n; return tree[n].n; } if(x<=mid) { return query(n*2,x); } else { return query(n*2+1,x); } } int cmp(pp a, pp b) { return a.h<b.h; } int dp[111111]; int main() { int i,j,k,l,m,n; while(scanf("%d",&n) == 1) { n++; s[0].h = 0; s[0].l = 1; s[0].r = 100000; s[0].v=0; for(i = 1; i<n; i++) { scanf("%d%d%d%d",&s[i].h,&s[i].l,&s[i].r,&s[i].v); } sort(s, s+n, cmp); build(1, 1, 100000); memset(dp,0,sizeof(dp)); for(i = 0;i<n; i++) { s[i].ln=query(1, s[i].l); s[i].rn=query(1, s[i].r); // cout<<s[i].ln<<" "<<s[i].rn<<endl; update(1, s[i].l, s[i].r, i); } dp[n-1]=100+s[n-1].v; for(i=n-1; i>0; i--) { dp[s[i].ln] = max(dp[s[i].ln], dp[i]+s[s[i].ln].v); dp[s[i].rn] = max(dp[s[i].rn], dp[i]+s[s[i].rn].v); } if(dp[0]<=0) dp[0]=-1; printf("%d\n",dp[0]); } return 0; } |