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 }

 

你可能感兴趣的:(poj)