• BZOJ3072 : [Pa2012]Two Cakes


    考虑DP,设$f[i][j]$表示考虑了$a[1..i]$和$b[1..j]$的最小代价。

    若$a[i]==b[j]$,则$f[i][j]=min(f[i-1][j],f[i][j-1])+1$。

    否则找到最大的$t$,满足$x$和$y$往前$t$个均不相等,此时$f[i][j]=f[i-t-1][j-t-1]+t$。

    对于$t$,可以通过在相应差值的序列中二分查找得到。

    对于DP的计算,可以通过搜索,并将那$n$个$a[i]==b[j]$的状态记忆化。

    因为对于每个没有记忆化的状态,均可以在$O(log n)$的时间内转化为那$n$个状态,所以总时间复杂度为$O(nlog n)$。

    #include<cstdio>
    const int N=1000010,BUF=13778000;
    int n,m,i,j,a[N],b[N],c[N],f[N],g[N<<1],nxt[N],st[N<<1],en[N<<1],q[N];char Buf[BUF],*buf=Buf;
    inline void read(int&a){for(a=0;*buf<48;buf++);while(*buf>47)a=a*10+*buf++-48;}
    inline void add(int x,int y){nxt[y]=g[x];g[x]=y;}
    inline int min(int a,int b){return a<b?a:b;}
    inline int pre(int l,int r,int x){
      int t=0,mid;
      while(l<=r)if(q[mid=(l+r)>>1]<=x)l=(t=mid)+1;else r=mid-1;
      return q[t];
    }
    int dp(int x,int y){
      if(!x||!y)return x+y;
      if(a[x]==b[y])return f[x]?f[x]:f[x]=min(dp(x-1,y),dp(x,y-1))+1;
      int t=pre(st[x-y+n],en[x-y+n],x);
      return t?dp(t,y-x+t)+x-t:(x>y?x:y);
    }
    int main(){
      fread(Buf,1,BUF,stdin);read(n);
      for(i=1;i<=n;i++)read(a[i]);
      for(i=1;i<=n;i++)read(b[i]),c[b[i]]=i;
      for(i=n;i;i--)add(i-c[a[i]]+n,i);
      for(i=1;i<n+n;en[i++]=m)for(st[i]=m+1,j=g[i];j;j=nxt[j])q[++m]=j;
      return printf("%d",dp(n,n)),0;
    }
    

      

  • 相关阅读:
    Json的转换
    Object类型的转为String类型
    如何获取实体类中的属性和属性值
    Collections.sort 的日期排序
    idea 报错 :error:java:Compilation failed:internal java compiler error
    System.nanoTime与System.currentTimeMillis比较
    Java中instanceof和isInstance区别详解
    避免实例化特有工具类
    加载Properties文件工具类:LoadConfig
    详解SVN 的使用
  • 原文地址:https://www.cnblogs.com/clrs97/p/5221792.html
Copyright © 2020-2023  润新知