zoukankan      html  css  js  c++  java
  • P2679 子串

    传送门

    思路:

      设 f [ i ][ j ][ k ][ 0/1 ] 表示 A 串匹配到第 i 个,B 串匹配到第 j 个,已经匹配到第 k 段,0: A[ i ] 与 B[ j ] 不匹配, 1: A[ i ] 与 B[ j ] 匹配。

      状态转移可分为 A[ i ] 与 B[ j ] 匹配和不匹配两种状态:

      ① 若不匹配, f [ i ][ j ][ k ][ 0 ] = f [ i-1 ][ j ][ k ][ 0 ] + f [ i-1 ][ j ][ k ][ 1 ] 。

      ② 匹配,f [ i ][ j ][ k ][ 1 ] = f [ i-1 ][ j-1 ][ k-1 ][ 1 ] + f [ i-1 ][ j-1 ][ k-1 ][ 0 ] + f [ i-1 ][ j-1 ][ k ][ 1 ] 。

      如果直接将 f 数组开到 4 维,128M 的空间明显不够。

      考虑到每次的状态转移只和前一次的状态有关,所以可以将 f 的第一维用二进制滚动 。

    Code:

    70 Points:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<deque>
    #include<map>
    #include<set>
    using namespace std;
    #define lck_max(a,b) ((a)>(b)?(a):(b))
    #define lck_min(a,b) ((a)<(b)?(a):(b))
    typedef long long LL;
    const int maxn=101;
    const int mod=1e9+7;
    LL n,m,K,ans,f[(maxn<<1)+(maxn<<3)][maxn<<1][maxn<<1][2];
    char s1[(maxn<<1)+(maxn<<3)],s2[maxn<<1];
    inline LL read()
    {
        LL kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
                kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    inline void out(LL xs)
    {
        if(!xs) {putchar(48); return;}
        if(xs<0) putchar('-'),xs=-xs;
        int kr[57],ls=0;
        while(xs) kr[++ls]=xs%10,xs/=10;
        while(ls) putchar(kr[ls]+48),ls--;
    }
    int main()
    {
        n=read();m=read();K=read();
        scanf("%s",s1+1);scanf("%s",s2+1);
        f[0][0][0][0]=1;
        for(LL i=1;i<=n;i++)
        {
            f[i][0][0][0]=1;
            for(LL j=1;j<=m;j++)
            {
                for(LL k=1;k<=K;k++)
                {
                    f[i][j][k][0]=(f[i-1][j][k][0]+f[i-1][j][k][1])%mod;
                    if(s1[i]==s2[j])
                        f[i][j][k][1]=(f[i-1][j-1][k][1]+f[i-1][j-1][k-1][0]+f[i-1][j-1][k-1][1])%mod;
                }
            }
        }
        out((f[n][m][K][0]+f[n][m][K][1])%mod);
    return 0;
    }

    100 Points:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<cstring>
    #include<string>
    #include<cstdlib>
    #include<stack>
    #include<vector>
    #include<queue>
    #include<deque>
    #include<map>
    #include<set>
    using namespace std;
    #define lck_max(a,b) ((a)>(b)?(a):(b))
    #define lck_min(a,b) ((a)<(b)?(a):(b))
    typedef long long LL;
    const int maxn=101;
    const int mod=1e9+7;
    bool pos=true;
    LL n,m,K,ans,f[2][maxn<<1][maxn<<1][2];
    char s1[(maxn<<1)+(maxn<<3)],s2[maxn<<1];
    inline LL read()
    {
        LL kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
                kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    inline void out(LL xs)
    {
        if(!xs) {putchar(48); return;}
        if(xs<0) putchar('-'),xs=-xs;
        int kr[57],ls=0;
        while(xs) kr[++ls]=xs%10,xs/=10;
        while(ls) putchar(kr[ls]+48),ls--;
    }
    int main()
    {
        n=read();m=read();K=read();
        scanf("%s",s1+1);scanf("%s",s2+1);
        f[0][0][0][0]=1;f[1][0][0][0]=1;
        for(LL i=1;i<=n;i++,pos^=1)
        {
            for(LL j=1;j<=m;j++)
            {
                for(LL k=1;k<=K;k++)
                {
                    f[pos][j][k][0]=(f[pos^1][j][k][0]+f[pos^1][j][k][1])%mod;
                    if(s1[i]==s2[j])
                        f[pos][j][k][1]=(f[pos^1][j-1][k][1]+f[pos^1][j-1][k-1][0]+f[pos^1][j-1][k-1][1])%mod;
                    else f[pos][j][k][1]=0;
                }
            }
        }
        out((f[n&1][m][K][0]+f[n&1][m][K][1])%mod);
    return 0;
    }
  • 相关阅读:
    C#利用反射动态调用类及方法
    系统程序监控软件
    SQL server 2008 安装和远程访问的问题
    sql server 创建临时表
    IIS 时间问题
    windows 2008 安装 sql server 2008
    sql server xml nodes 的使用
    Window 7sp1 安装vs2010 sp1 打开xaml文件崩溃
    CSS资源网址
    Could not load type 'System.ServiceModel.Activation.HttpModule' from assembly 'System.ServiceModel, Version=3.0.0.0
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9857652.html
Copyright © 2011-2022 走看看