• BZOJ2448 : 挖油


    $f[i][j]$表示仅考虑$[i,j]$区间的答案,则

    $f[i][j]=min(max(f[i][k-1],f[k+1][j])+a[k]),ileq kleq j$

    维护出$max$的分界点后用一堆线段树维护即可。

    时间复杂度$O(n^2log n)$。

    #include<cstdio>
    const int N=2005,inf=~0U>>1;
    int M,n,i,j,a[N],g,f[N][N];
    inline void up(int&a,int b){if(a>b)a=b;}
    struct ZKW{
    int v[4100];
    inline void ask(int x,int y,int&t){
      if(x>y)return;
      for(x+=M-1,y+=M+1;x^y^1;x>>=1,y>>=1){
        if(~x&1)up(t,v[x^1]);
        if(y&1)up(t,v[y^1]);
      }
    }
    inline void ins(int x,int y){for(x+=M;x;x>>=1)up(v[x],y);}
    inline void build(){for(int i=1;i<=n+M;i++)v[i]=inf;}
    }T1[N],T2[N];
    inline void add(int x,int y){
      if(x>1)T1[y].ins(x-1,f[x][y]+a[x-1]);
      if(y<n)T2[x].ins(y+1,f[x][y]+a[y+1]);
    }
    int main(){
      scanf("%d",&n);
      for(M=1;M<n+2;M<<=1);
      for(i=1;i<=n;i++)scanf("%d",&a[i]),T1[i].build(),T2[i].build();
      for(i=1;i<=n;i++)add(i,i-1);
      for(i=1;i<=n;i++)f[i][i]=a[i],add(i,i);
      for(i=n;i;i--)for(g=i,j=i+1;j<=n;j++){
        while(g<=j&&f[i][g-1]<f[g+1][j])g++;
        f[i][j]=inf;
        T1[j].ask(i,g-1,f[i][j]);
        T2[i].ask(g,j,f[i][j]);
        add(i,j);
      }
      return printf("%d",f[1][n]),0;
    }
    

      

  • 相关阅读:
    python标准库
    python常用标准库
    django-restframework-serializers
    Resources.UnloadUnusedAssets
    Shader 的 Blend
    C++STL queue
    C++STL stack
    C++STL deque
    C++STL容器重点
    C++STL 迭代器
  • 原文地址:https://www.cnblogs.com/clrs97/p/5475108.html
Copyright © 2020-2023  润新知