zoukankan      html  css  js  c++  java
  • 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;
    }
    

      

  • 相关阅读:
    Spring Batch与ETL工具比较
    Spring Batch基本概念
    SpringBatch介绍
    2019第51周日
    用arthas的watch方法观察执行方法的输入输出
    三人行必有我师
    用arthas查看JVM已加载的类及方法信息
    线上问题排查利器Arthas
    换个视觉
    Java Servlet:服务器小程序
  • 原文地址:https://www.cnblogs.com/clrs97/p/5221792.html
Copyright © 2011-2022 走看看