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

    题意:现在要从字符串 A 中取出 k 个互不重叠的非空子串,然后把这 k 个子串按照其在字符串 A 中出现的顺序依次连接起来得到一个新的字符串。请问有多少种方案可以使得这个新串与字符串 B 相等?

       注意:子串取出的位置不同也认为是不同的方案。

    输入输出样例

    输入样例#1:
    6 3 1 
    aabaab 
    aab
    输出样例#1: 
    2
    输入样例#2: 
    6 3 2 
    aabaab 
    aab
    输出样例#2: 
    7
    输入样例#3: 
    6 3 3 
    aabaab 
    aab
    输出样例#3: 
    7

    说明

    正解:DP

      设f[i][j][0/1]表示分成i个字串,当前在A的k(循环),B串在j(倒着枚举滚动),1:用当前i,2:总的方案

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cctype>
    using namespace std;
    #define int long long
    const int mod=1000000007LL;
    inline int read()
    {
        int f=1,x=0;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        return x*f;    
    }
    inline void put(int x)
    {
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline void in()
    {
        freopen("substring.in","r",stdin);
        freopen("substring.out","w",stdout);
    }
    inline void out()
    {
        fclose(stdin);
        fclose(stdout);
    }
    int f[250][250][2];
    int n;
    int m;
    int k;
    char a[1050];
    char b[250];
    inline void DPstart()
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=m;j>=1;j--)
            {
                for(int p=1;p<=k;p++)
                {
                    if(a[i]!=b[j])    //用i但i不与b相等,所以不合法,方案=0
                        f[p][j][1]=0;
                    else
                    {
                        if(p==1&&j==1)     //边界
                        {
                            f[p][j][1]=1;    //用当前的匹配一个,所以为1
                            f[p][j][0]++;    //相当于+=f[p][j][1];总方案
                            f[p][j][0]%=mod;  //别忘取模
                        }
                        else
                        {
                            (f[p][j][1]=f[p-1][j-1][0])%=mod;   //当前取,且单分
                            (f[p][j][0]+=f[p][j][1])%=mod;      //累加方案
                            if(i>=2)
                            {
                                if(a[i-1]==b[j-1])    //上一个也相同
                                {
                                    (f[p][j][0]+=f[p][j-1][1])%=mod;   //可以拼接把当前与上一个连起来的情况
                                    (f[p][j][1]+=f[p][j-1][1])%=mod;   //上一个和这个都取
                                }        
                            }
                            
                        }
                    }    
                }
            }
        }
    }
    signed main()
    {
    //    in();
        n=read();
        m=read();
        k=read();
        scanf("%s",a+1);
        scanf("%s",b+1);
        DPstart();
        put(f[k][m][0]%mod);
        out();
        return 0;
    }

      

  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/olinr/p/9577488.html
Copyright © 2011-2022 走看看