这题很容易想到O(n^2)的做法,但这样肯定是要超时的,对于第i个box,可以用线段树在logn的时间内找出小于mes[i].h且能拿到最多金子的box。

类型:线段树优化Dp。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 #define lson l,m,rt<<1
 5 #define rson m+1,r,rt<<1|1
 6 #define maxn 100005
 7 struct {
 8     int max;
 9 }setree[maxn<<2];
10 struct op{
11     int h,val;
12 }mes[maxn];
13 int num[maxn];
14 void build(int l,int r,int rt)
15 {
16     setree[rt].max=0;
17     if(l==r)
18     return;
19     int m=(l+r)>>1;
20     build(lson);
21     build(rson);
22 }
23 int binsearch(int l,int r,int c)
24 {
25     int m=(l+r)>>1;
26     if(num[m]==c)
27     return m;
28     if(c<num[m])
29     return binsearch(l,m-1,c);
30     else
31     return binsearch(m+1,r,c);
32 }
33 void pushup(int rt)
34 {
35     setree[rt].max=max(setree[rt<<1].max,setree[rt<<1|1].max);
36 }
37 void update(int l,int r,int rt,int num,int c)
38 {
39     if(l==r){
40         setree[rt].max=max(setree[rt].max,c);
41         return;
42     }
43     int m=(l+r)>>1;
44     if(num<=m)
45     update(lson,num,c);
46     else
47     update(rson,num,c);
48     pushup(rt);
49 }
50 int query(int l,int r,int rt,int L,int R)
51 {
52     if(L>R)
53     return 0;
54     if(L<=l&&r<=R)
55     return setree[rt].max;
56     int m=(l+r)>>1;
57     int ans=0;
58     if(L<=m)
59     ans=max(ans,query(lson,L,R));
60     if(R>m)
61     ans=max(ans,query(rson,L,R));
62     return ans;
63 }
64 int main()
65 {
66     int n;
67     while(~scanf("%d",&n)){
68         for(int i=1;i<=n;i++){
69             scanf("%d%d",&mes[i].h,&mes[i].val);
70             num[i]=mes[i].h;
71         }
72         sort(num+1,num+n+1);
73         int k=1;
74         for(int i=2;i<=n;i++)
75         if(num[i]!=num[i-1])
76         num[++k]=num[i];
77         build(1,k,1);
78         int ans=0;
79         for(int i=1;i<=n;i++){
80             int num=binsearch(1,k,mes[i].h);
81             int ret=query(1,k,1,1,num-1)+mes[i].val;
82             ans=max(ans,ret);
83             update(1,k,1,num,ret);
84         }
85         printf("%d\n",ans);
86     }
87     return 0;
88 }
AC Code