zoukankan      html  css  js  c++  java
  • [LUOGU] P2679 子串

    一开始用一个f数组转移,发现不太对,状态有重叠部分

    f[i][j][k]表示考虑了s的前i位,匹配到t的第j位,用了k个子串,且s的第i位必选

    g[i][j][k]表示考虑了s的前i位,匹配到t的第j位,用了k个子串,且s的第i位必不选


    考虑i的前一位:前一位选(作为结尾),前一位选(不作为结尾),前一位不选

    f[i][j][k]=f[i-1][j-1][k]+f[i-1][j-1][k-1]+g[i-1][j-1][k-1]

    第i位不选时继承状态

    g[i][j][k]=g[i-1][j][k]+f[i-1][j][k]

    滚动数组省一维

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #define int long long
    using namespace std;
    
    inline int rd(){
        int ret=0,f=1;char c;
        while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
        while(isdigit(c))ret=ret*10+c-'0',c=getchar();
        return ret*f;
    }
    
    const int MAXN=1007;
    const int MOD=1000000007;
    int n,m,num;
    
    char s[MAXN],t[MAXN];
    int f[2][MAXN][MAXN],g[2][MAXN][MAXN]; 
    
    signed main(){
        n=rd();m=rd();num=rd();
        scanf("%s%s",s+1,t+1);
        s[0]='a';t[0]='b';
        g[0][0][0]=1;
        for(int i=1;i<=n;i++){
            g[i&1][0][0]=1;
            for(int j=1;j<=m&&j<=i;j++){
                for(int k=1;k<=num;k++){
                    f[i&1][j][k]=g[i&1][j][k]=0;
                    g[i&1][j][k]=(g[(i-1)&1][j][k]+f[(i-1)&1][j][k])%MOD;
                    if(s[i]==t[j]){
                        f[i&1][j][k]=(f[(i-1)&1][j-1][k-1]+f[(i-1)&1][j-1][k]+g[(i-1)&1][j-1][k-1])%MOD;
                    }else{
                        f[i&1][j][k]=0;
                    }
                }
            }
        }
        cout<<(f[n&1][m][num]+g[n&1][m][num])%MOD;
        return 0;
    }

    本文来自博客园,作者:GhostCai,转载请注明原文链接:https://www.cnblogs.com/ghostcai/p/9399772.html

  • 相关阅读:
    PKU 学生的反馈 20091
    PKU 学生的反馈 2009 –2
    中国队有进步
    刚发现博客园又遇到了问题
    今日计划
    Delphi中使用多线程
    在老ASP中使用对象的对象生存期问题
    ASP与Javascript
    ASP & VBScript的错误处理
    对前一段时间学习网络和多线程编程的总结
  • 原文地址:https://www.cnblogs.com/ghostcai/p/9399772.html
Copyright © 2011-2022 走看看