线段树专辑—— hdu 3016 Man Down

http://acm.hdu.edu.cn/showproblem.php?pid=3016

挺有趣的一个以“是男人就下100层”为背景的题目,要求从最高处往下跳,跳到最下一层时候所得分数的最高值。

这题不难,首先将线段从低到高排序,用这些线段对区间进行染色,每次染色之前先询问一边从线段的左右节点跳下去所能到达的线段。记为一条路径。

最后从高到底根据我们所有的路径信息进行一次DP即可

View Code
  1 #include<iostream>
2 #include<string>
3 #include<algorithm>
4 using namespace std;
5
6 struct TREE
7 {
8 int l;
9 int r;
10 int id;
11 };
12
13 TREE tree[500000];
14 int n;
15
16 struct LINE
17 {
18 int h;
19 int l;
20 int r;
21 int w;
22 };
23
24 LINE line[100000];
25
26 int cmp(LINE a,LINE b)
27 {
28 return a.h<b.h;
29 }
30
31 struct PATH
32 {
33 int l;
34 int r;
35 };
36
37 PATH path[100001];
38
39 int max(int a,int b)
40 {
41 return a>b?a:b;
42 }
43
44 void build(int i,int l,int r)
45 {
46 tree[i].l=l;
47 tree[i].r=r;
48 tree[i].id=0;
49 if(l==r)
50 return;
51 int mid=(l+r)/2;
52 build(2*i,l,mid);
53 build(2*i+1,mid+1,r);
54 }
55
56 void updata(int i,int l,int r,int id)
57 {
58 if(tree[i].l>r || tree[i].r<l)
59 return;
60 if(tree[i].l>=l && tree[i].r<=r)
61 {
62 tree[i].id=id;
63 return;
64 }
65 if(tree[i].id!=-1)
66 {
67 tree[2*i].id=tree[2*i+1].id=tree[i].id;
68 tree[i].id=-1;
69 }
70 updata(2*i,l,r,id);
71 updata(2*i+1,l,r,id);
72 }
73
74 int query(int i,int w)
75 {
76 if(tree[i].id!=-1 && tree[i].l<=w && tree[i].r>=w)
77 return tree[i].id;
78 else
79 {
80 int mid=(tree[i].l+tree[i].r)/2;
81 if(w<=mid)
82 {
83 return query(2*i,w);
84 }
85 else
86 {
87 return query(2*i+1,w);
88 }
89 }
90 }
91
92 int dp[100001];
93
94 int main()
95 {
96 int i,k;
97 //freopen("in.txt","r",stdin);
98 while(scanf("%d",&n)!=EOF)
99 {
100 k=0;
101 for(i=1;i<=n;i++)
102 {
103 scanf("%d%d%d%d",&line[i].h,&line[i].l,&line[i].r,&line[i].w);
104 if(line[i].l>k)
105 k=line[i].l;
106 if(line[i].r>k)
107 k=line[i].r;
108 }
109 sort(line+1,line+n+1,cmp);
110 build(1,1,k);
111 for(i=1;i<=n;i++)
112 {
113 path[i].l=query(1,line[i].l); //查找从第i条边的左节点下去将到达的边
114 path[i].r=query(1,line[i].r); //...............右..................
115 updata(1,line[i].l,line[i].r,i);
116 }
117 memset(dp,0,sizeof(dp));
118 dp[n]=100+line[n].w;
119 for(i=n;i>=1;i--) //简单的DP
120 {
121 if(dp[i])
122 {
123 dp[path[i].l]=max(dp[path[i].l],dp[i]+line[path[i].l].w);
124 dp[path[i].r]=max(dp[path[i].r],dp[i]+line[path[i].r].w);
125 }
126 }
127 if(dp[0]>0)
128 {
129 printf("%d\n",dp[0]);
130 }
131 else
132 {
133 printf("-1\n");
134 }
135 }
136 return 0;
137 }



posted @ 2011-11-12 16:59  Accept  阅读(457)  评论(0编辑  收藏  举报