zoukankan      html  css  js  c++  java
  • POJ2374 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 }
  • 相关阅读:
    获取计算机名称
    imagelist用法
    cxgrid的ImageComboBox属性学习
    MlskincolorButton使用方法
    delphi实现窗体组建随窗体大小改变而改变
    判断路径下文件是否存在
    Delphi 按Esc快捷键退出程序的简单方法
    pagecontrol
    LinkedList源码解析
    ArrayList源码分析
  • 原文地址:https://www.cnblogs.com/zhsl/p/2975472.html
Copyright © 2011-2022 走看看