• 【刷题】【序列dp】color length


    典型的代价优先计算dp

    难点就在计算代价上。。。

    很巧的是,每次合并,代价就是i,j组成的序列中,开始了但是没有结束的字母种类数

    【1】普通dp tle不知道多少个点

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    inline int read()
    {
        int x=0;char c=getchar();
        while(c<'0' || c>'9' ) c=getchar();
        while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
        return x;
    }
    inline void wr(int x)
    {
        if(x>=10) wr(x/10);
        putchar(x%10+'0');
    }
    
    int n;
    const int N=5e3+3;
    char a[N],b[N];
    int la,lb,da[N],db[N];
    int sum[26],cnt[2][N][26];
    
    int w[N][N];
    int f[N][N];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(cnt,0,sizeof(cnt));
            memset(sum,0,sizeof(sum));
            la=lb=0;
            //pre0
            scanf("%s%s",a+1,b+1);
            while(a[++la])
                da[la]=a[la]-'A',sum[da[la]]++,cnt[0][la][da[la]]++;
            while(b[++lb])
                db[lb]=b[lb]-'A',sum[db[lb]]++,cnt[1][lb][db[lb]]++;
            la--,lb--;
            for(int i=1;i<=la;i++)
            {
                int res=0;
                for(int j=0;j<26;j++)
                {
                    cnt[0][i][j]+=cnt[0][i-1][j];
                    if(cnt[0][i][j] && cnt[0][i][j]!=sum[j] )
                        res++;
                }
                w[i][0]=res;
            }
            for(int i=1;i<=lb;i++)
            {
                int res=0;
                for(int j=0;j<26;j++)
                {
                    cnt[1][i][j]+=cnt[1][i-1][j];
                    if(cnt[1][i][j] && cnt[1][i][j]!=sum[j] )
                        res++;
                }
                w[0][i]=res;
            }
            //pre1
            for(int i=1;i<=la;i++)
                for(int j=1;j<=lb;j++)
                {
                    w[i][j]=w[i][j-1];
                    if(cnt[0][i][db[j]] + cnt[1][j][db[j]] ==sum[db[j]] )
                        w[i][j]--;
                    if(!cnt[1][j-1][db[j]] && !cnt[0][i][db[j]] )
                        w[i][j]++;
                }
            //work
            memset(f,0x3f,sizeof(f));
            f[0][0]=0;
            for(int j=1;j<=lb;j++) f[0][j]=f[0][j-1]+w[0][j-1];
            for(int i=1;i<=la;i++)
            {
                f[i][0]=f[i-1][0]+w[i-1][0];
                for(int j=1;j<=lb;j++)
                    f[i][j]=min(f[i][j-1]+w[i][j-1],f[i-1][j]+w[i-1][j] ),
                    printf("%d ",f[i][j]); 
                printf("
    ");
            }
            wr(f[la][lb]),putchar('
    ');
        }
        
        return 0;
    }
    View Code

    【2】滚动数组优化 时间和空间

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    inline int read()
    {
        int x=0;char c=getchar();
        while(c<'0' || c>'9' ) c=getchar();
        while(c>='0'&&c<='9' ) x=(x<<3)+(x<<1)+c-'0',c=getchar();
        return x;
    }
    inline void wr(int x)
    {
        if(x>=10) wr(x/10);
        putchar(x%10+'0');
    }
    
    int n;
    const int N=5e3+3;
    char a[N],b[N];
    int la,lb,da[N],db[N];
    int sum[26],cnt[2][N][26];
    
    int w[2][N];
    int f[2][N];
    
    int main()
    {
        int T;
        scanf("%d",&T);
        while(T--)
        {
            memset(cnt,0,sizeof(cnt));
            memset(sum,0,sizeof(sum));
            memset(f,0x3f,sizeof(f));
            la=lb=0;
            //pre0
            scanf("%s%s",a+1,b+1);
            while(a[++la])
                da[la]=a[la]-'A',sum[da[la]]++,cnt[0][la][da[la]]++;
            while(b[++lb])
                db[lb]=b[lb]-'A',sum[db[lb]]++,cnt[1][lb][db[lb]]++;
            la--,lb--;
            for(int i=1;i<=la;i++) 
                for(int j=0;j<26;j++) cnt[0][i][j]+=cnt[0][i-1][j];
            for(int i=1;i<=lb;i++) 
                for(int j=0;j<26;j++) cnt[1][i][j]+=cnt[1][i-1][j];
            
            f[0][0]=w[0][0]=0; 
            for(int i=1;i<=lb;i++)
            {
                w[0][i]=w[0][i-1];
                if(!cnt[1][i-1][db[i]] ) w[0][i]++;
                if( cnt[1][i][db[i]] == sum[db[i]] ) w[0][i]--;
                f[0][i]=f[0][i-1]+w[0][i-1];
            }
            for(int i=1;i<=la;i++)
            {
                int nw=i&1,pre=nw^1;
                //pre1
                w[nw][0]=w[pre][0];//对应w[i][0] 
                if(cnt[0][i][da[i]] == sum[da[i]]) w[nw][0]--;
                if(cnt[0][i-1][da[i]] == 0 ) w[nw][0]++; 
                for(int j=1;j<=lb;j++)//对应w[i][j] 
                {
                    w[nw][j]=w[nw][j-1];
                    if(cnt[0][i][db[j]] + cnt[1][j][db[j]] ==sum[db[j]] ) w[nw][j]--;
                    if(!cnt[1][j-1][db[j]] && !cnt[0][i][db[j]] ) w[nw][j]++;
                }
                //work
                f[nw][0]=f[pre][0]+w[pre][0];
                for(int j=1;j<=lb;j++)
                    f[nw][j]=min(f[pre][j]+w[pre][j],f[nw][j-1]+w[nw][j-1]);          
            }
            wr(f[la&1][lb]),putchar('
    ');
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    数据库索引(Oracle和Mysql)学习总结
    个人开源Git地址
    关于SQL优化这些你了解吗?
    Java项目排查cpu负载高
    Java Bean与Map之间相互转化的实现
    Maven项目改为spring boot项目的方法
    spring boot从redis取缓存发生java.lang.ClassCastException异常
    MySQL优化之Explain命令解读
    阿里巴巴校招四面经验分享
    HDBS之应用代码优化
  • 原文地址:https://www.cnblogs.com/xwww666666/p/11769403.html
Copyright © 2020-2023  润新知