zoukankan      html  css  js  c++  java
  • BZOJ1481 : Navigation Game

    设$f[i][j][k]$表示从最后一行某个$H$走到$(i,j)$且在第$i$行只经过了$(i,j)$,途中经过了$k$次$F$的最小代价。

    $A[i][j][k]$表示从下一行$leq i$的某个$f[old][x][j]$且前$x-1$个有$k$个$F$的位置走过来的最小代价。

    $B[i][j][k]$表示从下一行$geq i$的某个$f[old][x][j]$且前$x$个有$k$个$F$的位置走过来的最小代价。

    $A$和$B$的转移都具有决策单调性,分治求解即可。然后用$A$和$B$计算当前行的$f$。

    时间复杂度$O(nmlog m)$。

    #include<cstdio>
    const int N=1010,inf=~0U>>1;
    int n,m,M,i,j,k,x,y,f[N][N][2],v[N][N],ans=inf;
    int A[N][2][2],B[N][2][2],g[N][2],so[N],sf[N],s1[N],s2[N];
    char a[N][N];
    inline void up(int&x,int y){if(x>y)x=y;}
    void getA(int l,int r,int dl,int dr){
      int m=(l+r)>>1,dm=m,&ret=A[m][x][y];
      if(dm<dl)dm=dl;
      if(dm>dr)dm=dr;
      ret=inf;
      for(int i=dl;i<=dr&&i<=m;i++){
        if(g[i][x]==inf||sf[i-1]!=y||so[m]>so[i-1])continue;
        int t=g[i][x]+s1[m]-s1[i-1]-(s2[m]-s2[i-1])*i;
        if(t<ret)ret=t,dm=i;
      }
      if(l<m)getA(l,m-1,dl,dm);
      if(r>m)getA(m+1,r,dm,dr);
    }
    void getB(int l,int r,int dl,int dr){
      int m=(l+r)>>1,dm=m,&ret=B[m][x][y];
      if(dm<dl)dm=dl;
      if(dm>dr)dm=dr;
      ret=inf;
      for(int i=dr;i>=dl&&i>=m;i--){
        if(g[i][x]==inf||sf[i]!=y||so[i]>so[m-1])continue;
        int t=g[i][x]-s1[i]+s1[m-1]+(s2[i]-s2[m-1])*i;
        if(t<ret)ret=t,dm=i;
      }
      if(l<m)getB(l,m-1,dl,dm);
      if(r>m)getB(m+1,r,dm,dr);
    }
    int main(){
      scanf("%d%d",&n,&m);M=m;
      for(i=1;i<=n;i++)scanf("%s",a[i]+1);
      for(j=1;j<=m;j++){
        if(a[1][j]=='.')a[1][j]='O';
        if(a[n][j]=='.')a[n][j]='O';
      }
      for(i=1;i<=n;i++)for(j=1;j<=m;j++){
        v[i][j]=1;
        if(a[i][j]=='B')v[i][j]=0;
        if(a[i][j]=='S')v[i][j]=2;
      }
      for(i=1;i<=n;i++)for(j=1;j<=m;j++)for(k=0;k<2;k++)f[i][j][k]=inf;
      for(j=1;j<=m;j++)if(a[n][j]=='H')f[n][j][0]=0;
      for(i=n-1;i;i--){
        for(j=1;j<=m;j++){
          so[j]=so[j-1]+(a[i+1][j]=='O');
          sf[j]=sf[j-1]^(a[i+1][j]=='F');
          s1[j]=s1[j-1]+j*v[i+1][j];
          s2[j]=s2[j-1]+v[i+1][j];
          for(k=0;k<2;k++)g[j][k]=f[i+1][j][k];
        }
        for(x=0;x<2;x++)for(y=0;y<2;y++)getA(1,m,1,m);
        for(x=0;x<2;x++)for(y=0;y<2;y++)getB(1,m,1,m);
        for(j=1;j<=m;j++)if(a[i][j]!='O')for(x=0;x<2;x++)for(y=0;y<2;y++){
          up(f[i][j][x^y^sf[j]],A[j][x][y]);
          up(f[i][j][x^y^sf[j-1]],B[j][x][y]);
        }
        for(j=1;j<=m;j++)for(k=0;k<2;k++)if(f[i][j][k]<inf)f[i][j][k]+=v[i][j];
      }
      for(j=1;j<=m;j++)up(ans,f[1][j][1]);
      if(ans<inf)printf("%d",ans);else puts("Victory of Darkness");
      return 0;
    }
    

      

  • 相关阅读:
    vue插件(还真是第一次接触)
    Vue父组件向子组件传值以及data和props的区别
    Vue v-bind与v-model的区别
    vue 异步渲染
    vue动态加载不同的组件(分内部和外部组件)
    vue自定义组件的递归
    作用域插槽模板迭代的次数,取决于组件内部独立slot的数量
    说说 Vue.js 中的 v-cloak 指令
    C语言 system
    C语言 有符号、无符号
  • 原文地址:https://www.cnblogs.com/clrs97/p/5790857.html
Copyright © 2011-2022 走看看