• BZOJ1330 : Editing a Book


    注意到答案不超过$5$,因此可以考虑BFS求出距离起始态或者终止态不超过$2$的所有状态。

    设它们到起始态、终止态的距离分别为$f[S],g[S]$,则$ans=min(5,f[S]+g[S])$。

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

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef unsigned long long ll;
    const int N=12,M=363000;
    int n,i,j,k,a[N],len[N],S,x,z,v[M],g[M],h,t,q[M],ans;ll f[N][M];
    inline ll encode(){
      ll t=0;
      for(int i=0;i<n;i++)t=t<<4|a[i];
      return t;
    }
    inline int getid(ll x){
      int l=0,r=len[n]-1;
      while(l<=r){
        int mid=(l+r)>>1;
        if(f[n][mid]==x)return mid;
        if(f[n][mid]<x)l=mid+1;else r=mid-1;
      }
    }
    inline void ext(int x){
      if(~v[x])return;
      v[q[++t]=x]=z;
    }
    int main(){
      for(n=2;n<=9;n++){
        for(i=0;i<n;i++)a[i]=i;
        do{f[n][len[n]++]=encode();}while(next_permutation(a,a+n));
        sort(f[n],f[n]+len[n]);
      }
      while(~scanf("%d",&n)){
        if(!n)return 0;
        for(i=0;i<n;i++)scanf("%d",&a[i]),a[i]--;
        if(n==1){puts("0");continue;}
        S=getid(encode());
        h=1,t=0;
        for(i=0;i<len[n];i++)v[i]=-1;
        z=0;
        ext(S);
        while(h<=t){
          z=v[x=q[h++]]+1;
          if(z>2)continue;
          ll O=f[n][x];
          for(i=1;i<n;i++)for(j=i;j<n;j++){
            ll U=(1ULL<<((j-i+2)*4))-1,F=O;
            int L=(j-i+1)*4;
            for(k=4*(i-1);k>=0;k-=4){
              ll A=(F>>k)&U;
              F^=(A^((A>>4)|(A&15)<<L))<<k;
              ext(getid(F));
            }
          }
        }
        for(i=0;i<len[n];i++)g[i]=v[i],v[i]=-1;
        h=1,t=z=0;
        ext(0);
        while(h<=t){
          z=v[x=q[h++]]+1;
          if(z>2)continue;
          ll O=f[n][x];
          for(i=1;i<n;i++)for(j=i;j<n;j++){
            ll U=(1ULL<<((j-i+2)*4))-1,F=O;
            int L=(j-i+1)*4;
            for(k=4*(i-1);k>=0;k-=4){
              ll A=(F>>k)&U;
              F^=(A^((A>>4)|(A&15)<<L))<<k;
              ext(getid(F));
            }
          }
        }
        for(ans=5,i=0;i<len[n];i++)if(~v[i]&&~g[i])ans=min(ans,v[i]+g[i]);
        printf("%d
    ",ans);
      }
      return 0;
    }
    

      

  • 相关阅读:
    Codeforces461E Appleman and a Game 做题心得
    关于贪心问题的处理
    各种容斥 笔记
    博弈论 笔记
    家庭多个路由器组网方案(AP+AC)
    21.06.06 训练赛
    Redirect...
    Web Api实践系列(三)route特性使用
    《Red Tuner》隐私政策
    前缀和-1915. 最美子字符串的数目
  • 原文地址:https://www.cnblogs.com/clrs97/p/6321773.html
Copyright © 2020-2023  润新知