zoj3381

 1 /*
 2 题意:n天,第i天可以获得的值为vi,如果获得第i天的值,那么下一次能获得的值
 3 只能在[i+x[i],i+y[i]-1]天中取,为最大能获得多少值;
 4 
 5 分析:直接DP,每次维护经过前i-1天第i天能可以获得的最大值,用线段树维护就要同时记录下区间的最大最小值;
 6 表示区间内的可能获得最大值的最大值和最小值;
 7 另一种DP的思路,dp[i]表示选了第i天,最终能获得的最大值,那么dp[i]=v[i]+max(dp[i+x[i]],dp[i+y[i]-1]);
 8 直接用线段树维护区间最大值就可以了;
 9 
10 */
11 #include<cstdio>
12 #include<cstring>
13 #include<cstdlib>
14 #include<iostream>
15 #include<cmath>
16 #include<algorithm>
17 #define lson l,m,rt<<1
18 #define rson m+1,r,rt<<1|1
19 using namespace std;
20 const int N=50000+10;
21 int maxv[N<<2],minv[N<<2],col[N<<2];
22 int x[N],y[N],v[N];
23 int n;
24 void pushup(int rt){
25     maxv[rt]=max(maxv[rt<<1],maxv[rt<<1|1]);
26     minv[rt]=min(minv[rt<<1],minv[rt<<1|1]);
27 }
28 void build(int l,int r,int rt){
29     maxv[rt]=minv[rt]=col[rt]=0;
30     if (l==r) return ;
31     int m=(l+r)>>1;
32     build(lson);build(rson);
33 }
34 void pushdown(int rt){
35     if (col[rt]){
36         if (col[rt]>=maxv[rt<<1]){
37             maxv[rt<<1]=minv[rt<<1]=col[rt];
38         }else if (col[rt]>minv[rt<<1])minv[rt<<1]=col[rt];
39         col[rt<<1]=max(col[rt<<1],col[rt]);
40 
41         if (col[rt]>=maxv[rt<<1|1]){
42             maxv[rt<<1|1]=minv[rt<<1|1]=col[rt];
43         }else if (col[rt]>minv[rt<<1|1])minv[rt<<1|1]=col[rt];
44         col[rt<<1|1]=max(col[rt<<1|1],col[rt]);
45 
46         col[rt]=0;
47     }
48 }
49 void update(int L,int R,int v,int l,int r,int rt){
50     if (v<=minv[rt]) return;
51     if (L<=l && r<=R){
52         if (v>=maxv[rt]){
53             maxv[rt]=minv[rt]=v;
54         }else if (v>minv[rt]){
55             minv[rt]=v;
56         }
57         col[rt]=max(col[rt],v);
58         return;
59     }
60     int m=(l+r)>>1;
61     pushdown(rt);
62     if (L<=m) update(L,R,v,lson);
63     if (m< R) update(L,R,v,rson);
64     pushup(rt);
65 }
66 int query(int L,int l,int r,int rt){
67     if (l==r){
68         return maxv[rt];
69     }
70     int m=(l+r)>>1;
71     pushdown(rt);
72     if(L<=m) return query(L,lson);
73     else return query(L,rson);
74 }
75 int main(){
76     while (~scanf("%d",&n)){
77         for (int i=1;i<=n;i++){
78             scanf("%d%d%d",&v[i],&x[i],&y[i]);
79         }
80         build(1,n+1,1);
81         int ret=0;
82         for (int i=1;i<=n;i++){
83             int t=query(i,1,n+1,1);
84             if (i!=1 && t==0) continue;
85             t+=v[i];
86         //    cout<<i<<" "<<t<<endl;
87             if (t>ret) ret=t;
88             int l=min(n+1,i+x[i]),r=min(n+1,i+y[i]-1);
89             update(l,r,t,1,n+1,1);
90         }
91         printf("%d\n",ret);
92     }
93 
94     return 0;
95 }

 

posted @ 2013-05-22 16:02  Rabbit_hair  阅读(162)  评论(0编辑  收藏  举报