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;
    }

      

  • 相关阅读:
    SCRUM站立会议
    燃尽图
    第一次作业----词频统计
    构建之法读感
    final 评论 II
    final 评论 I
    第十一周PSP
    学期回顾
    第十周PSP
    Gradle学习笔记
  • 原文地址:https://www.cnblogs.com/olinr/p/9577488.html
Copyright © 2011-2022 走看看