zoukankan      html  css  js  c++  java
  • 萌萌哒的第五题

    1100 - 萌萌哒的第五题

    Time Limit:10s Memory Limit:128MByte

    Submissions:353Solved:76

    DESCRIPTION

    给出一个长度为m的字符串,请问有多少个长度为n的字符串不存在子串等于给出的字符串。为了简化问题,我们规定所有字符串只包含小写英文字母。
    输入数据:
    包含多组输入数据(<=15),每组数据:
    第一行包含两个整数n和m(1 <= n,m <= 1000)
    第二行包含一个长度为m的字符串,只含有小写字母。

    INPUT
    包含多组输入数据(<=15),每组数据: 第一行包含两个整数n和m(1 <= n,m <= 1000) 第二行包含一个长度为m的字符串,只含有小写字母。
    OUTPUT
    每组数据输出一行,表示答案,这个答案可能会很大,所以只需要输出答案对10^9+7求余的结果。
    SAMPLE INPUT
    2 2 aa 3 2 aa
    SAMPLE OUTPUT
    675 17525
    SOLUTION
     
    讲道理这个问题不是那么的难,但是我还是不知道怎么从dp那里得到思路,但是知道了dp发现这个问题还是不是那么难的。。。。
    就是一般没有办法解决的问题好好的想一下dp看看能不能做就ok了。。。
    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=1e3+4;
    const int mod=1e9+7;
    char p[N],a[N];
    ll c[N][N],dp[N][N];
    int f[N];
    void getfail(char *p,int *f)
    {
        int m=strlen(p);
        f[0]=0; f[1]=0;
        for(int i=1;i<m;i++)
        {
            int j=f[i];
            while(j&&p[i]!=p[j]) j=f[j];
            f[i+1]=p[i]==p[j]?j+1:0;
        }
    }
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            memset(dp,0,sizeof(dp));
            memset(p,'',sizeof(p));
            memset(f,0,sizeof(f));
            memset(c,0,sizeof(c));
            getchar();
            for(int i=1;i<=m;i++) scanf("%c",&a[i]);
            for(int i=1;i<=m;i++) p[i-1]=a[i];
            getfail(p,f);
            for(int i=1;i<=m;i++)
            {
                for(int k=0;k<26;k++)
                {
                    int x=i-1;
                    char ch='a'+k;
                    if(ch==a[i]) c[i][k]=i;
                    else
                    {
                        while(x)
                        {
    
                            if(ch==p[x])
                            {
                                break;
                            } x=f[x];
                        }
                        if(ch==p[x]) c[i][k]=x+1;// 这里的细节问题,好像只有我这种傻逼才会不注意吧。
                        else c[i][k]=0;
                    }
                }
            }
            dp[0][0]=1;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    for(int k=0;k<26;k++)
                    {
                        dp[i][c[j][k]]=dp[i][c[j][k]]%mod+dp[i-1][j-1]%mod;
                        dp[i][c[j][k]]%=mod;
                    }
                }
            }
            ll sum=0;
            for(int i=0;i<m;i++)
            {
                sum=sum%mod+dp[n][i]%mod;
                sum%=mod;
            }
            printf("%lld
    ",sum);
        }
    }
    

    最近状态不怎么好,所以说的话最近就花多点的时间好好的A题,然后就是为了以后的省赛做准备,,,,

    就是利用任何可以利用的时间好好的A题。。。。

  • 相关阅读:
    Linux IO接口 监控 (iostat)
    linux 防火墙 命令
    _CommandPtr 添加参数 0xC0000005: Access violation writing location 0xcccccccc 错误
    Visual Studio自动关闭
    Linux vsftpd 安装 配置
    linux 挂载外部存储设备 (mount)
    myeclipse 9.0 激活 for win7 redhat mac 亲测
    英文操作系统 Myeclipse Console 乱码问题
    Linux 基本操作命令
    linux 查看系统相关 命令
  • 原文地址:https://www.cnblogs.com/Heilce/p/6509395.html
Copyright © 2011-2022 走看看