zoukankan      html  css  js  c++  java
  • 【bzoj2121】字符串游戏 【动态规划dp】

    题目链接
    感觉这个dp还是蛮棒棒的^^
    我们让f[i][j][a][b]=0/1表示大串中i~j的子串与第a个小串1~b的字串是否完全相同,ok[i][j]=0/1表示大串中i~j的子串能否全部拿空,dp[i]表示大串前i个字符最少剩下几个。
    则有状态转移方程
    f[i][j][a][b]|=(f[i][j1][a][b1] and t[j]==s[a][b])||(f[i][k][a][b] and ok[k+1][j])(k=i..j1)
    ok[i][j]|=f[i][j][a][len[a]]
    dp[i]=min(dp[i1]+1,dp[j] and ok[j+1][i])
    观察发现通过状压可以压掉一维的空间复杂度和时间复杂度。于是就可以乱搞了。

    非状压代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int lt,n,ls[35],ok[151][151],f[151][151][31][21],dp[151];
    char t[155],s[35][25];
    int main(){
        scanf("%s",t+1);
        lt=strlen(t+1);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]+1);
            ls[i]=strlen(s[i]+1);
        }
        for(int i=1;i<=lt;i++){
            for(int j=1;j<=n;j++){
                if(t[i]==s[j][1]){
                    f[i][i][j][1]=1;
                    ok[i][i]|=f[i][i][j][ls[j]];
                }
            }
        }
        for(int i=lt;i>=1;i--){
            for(int j=i+1;j<=lt;j++){
                for(int a=1;a<=n;a++){
                    for(int b=1;b<=ls[a];b++){
                        f[i][j][a][b]|=(f[i][j-1][a][b-1]&&t[j]==s[a][b]);
                        for(int k=i;k<=j-1;k++){
                            f[i][j][a][b]|=(f[i][k][a][b]&&ok[k+1][j]);
                        }
                    }
                    ok[i][j]|=f[i][j][a][ls[a]];
                }
            }
        }
        for(int i=1;i<=lt;i++){
            dp[i]=dp[i-1]+1;
            for(int j=0;j<i;j++){
                if(ok[j+1][i]){
                    dp[i]=min(dp[i],dp[j]);
                }
            }
        }
        printf("%d
    ",dp[lt]);
        return 0;
    }

    状压代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int lt,n,bin[35],ls[35],ok[151][151],f[151][151][31],dp[151];
    char t[155],s[35][25];
    int main(){
        scanf("%s",t+1);
        lt=strlen(t+1);
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]+1);
            ls[i]=strlen(s[i]+1);
        }
        bin[0]=1;
        for(int i=1;i<=30;i++){
            bin[i]=bin[i-1]<<1;
        }
        for(int i=1;i<=lt;i++){
            for(int j=1;j<=n;j++){
                if(t[i]==s[j][1]){
                    f[i][i][j]|=bin[1];
                    ok[i][i]|=(f[i][i][j]&bin[ls[j]]);
                }
            }
        }
        for(int i=lt;i>=1;i--){
            for(int j=i+1;j<=lt;j++){
                for(int a=1;a<=n;a++){
                    for(int b=1;b<=ls[a];b++){
                        f[i][j][a]|=((f[i][j-1][a]&bin[b-1])&&t[j]==s[a][b])*bin[b];
                    }
                    for(int k=i;k<=j-1;k++){
                        if(ok[k+1][j]){
                            f[i][j][a]|=f[i][k][a];
                        }
                    }
                    ok[i][j]|=(f[i][j][a]&bin[ls[a]]);
                }
            }
        }
        for(int i=1;i<=lt;i++){
            dp[i]=dp[i-1]+1;
            for(int j=0;j<i;j++){
                if(ok[j+1][i]){
                    dp[i]=min(dp[i],dp[j]);
                }
            }
        }
        printf("%d
    ",dp[lt]);
        return 0;
    }
  • 相关阅读:
    datagridview 数据刷新 从新绑定
    SVN 出现This client is too old to work with working copy...错误
    【转】ASPX和HTML获取系统根目录的路径
    C#程序最小化到托盘图标
    Winform的html编辑控件htmleditor 有时候无法为里面HTML属性初始化
    C# HttpWebRequest保存cookies模拟登录的方法【z】【解决】
    快速生成解决方案 ctrl + shilf + b
    datagridview只允许单选
    数据库int类型 才可以自增长
    C# dataTable实用例
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476867.html
Copyright © 2011-2022 走看看