POJ-2374 Fence Obstacle Course DP+线段树优化

  题目链接:http://poj.org/problem?id=2374

  这个题目坑了好久啊,题意看错了,bs自己。

  其实不难的,状态方程容易相处来,每个fence只有两种状态,即左边下去和右边下去,如果要知道当前状态的最优情况,就必须知道前面所有状态的最优情况,最坏情况下复杂度O(n^2)。但显然可以发现前面有很多的状态都不能到达当前状态于,因为前面的有些状态被覆盖了,于是我们可以用线段树来优化,在log(n)的时间里找到可以到达当前状态的fence。虽然在log(n)的时间里找出了状态,但是还是有比较多的状态,还可以继续优化。注意到编号为 i 的fence和所有编号为 1,2,,,,i-1 的fence,编号为 i 的fence只能有前面一个到达,因此我们可以倒叙来DP。

 1 //STATUS:C++_AC_329MS_4044KB
 2 #include<stdio.h>
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<math.h>
 6 #include<iostream>
 7 #include<string>
 8 #include<algorithm>
 9 #include<vector>
10 #include<queue>
11 #include<stack>
12 #include<map>
13 using namespace std;
14 #define LL __int64
15 #define pii pair<int,int>
16 #define Max(a,b) ((a)>(b)?(a):(b))
17 #define Min(a,b) ((a)<(b)?(a):(b))
18 #define mem(a,b) memset(a,b,sizeof(a))
19 #define lson l,mid,rt<<1
20 #define rson mid+1,r,rt<<1|1
21 const int N=50010,M=100000,INF=0x3f3f3f3f,MOD=100000000;
22 const double DNF=100000000000;
23 
24 int l[N][2],f[N][2],sta[200010<<2];
25 int n,s,w,a,b;
26 
27 void update(int l,int r,int rt)
28 {
29     if(a<=l && r<=b){
30         sta[rt]=w;
31         return;
32     }
33     if(sta[rt]>=0){
34         sta[rt<<1]=sta[rt<<1|1]=sta[rt];
35         sta[rt]=-1;
36     }
37     int mid=(l+r)>>1;
38     if(a<=mid)update(lson);
39     if(b>mid)update(rson);
40 }
41 
42 void query(int l,int r,int rt)
43 {
44     if(sta[rt]!=-1){
45         w=sta[rt];
46         return;
47     }
48     int mid=(l+r)>>1;
49     if(a<=mid)query(lson);
50     else query(rson);
51 }
52 
53 int main()
54 {
55  //   freopen("in.txt","r",stdin);
56     int i,j,ans;
57     while(~scanf("%d%d",&n,&s))
58     {
59         mem(f,INF);
60         mem(sta,0);
61         for(i=1;i<=n;i++){
62             scanf("%d%d",&l[i][0],&l[i][1]);
63             l[i][0]+=M;l[i][1]+=M;
64         }
65         f[0][0]=f[0][1]=0;
66         l[0][0]=l[0][1]=M;
67         for(i=1;i<=n;i++){
68             w=0;a=l[i][0];
69             query(0,M<<1,1);
70             f[i][0]=Min(f[w][0]+abs(l[i][0]-l[w][0]),f[w][1]+abs(l[i][0]-l[w][1]));
71             w=0;a=l[i][1];
72             query(0,M<<1,1);
73             f[i][1]=Min(f[w][0]+abs(l[i][1]-l[w][0]),f[w][1]+abs(l[i][1]-l[w][1]));
74             a=l[i][0],b=l[i][1];w=i;
75             update(0,M<<1,1);
76         }
77 
78         ans=Min(f[n][0]+abs(s+M-l[n][0]),f[n][1]+abs(s+M-l[n][1]));
79         printf("%d\n",ans);
80     }
81     return 0;
82 }

 

posted @ 2013-03-22 14:10  zhsl  阅读(538)  评论(0编辑  收藏  举报