• poj1618


    题意:有n个长度为len的模式串,问在所有长度为L的串中有多少个串符合如下条件:该串所有长度为len的子串都在这n个模式串中。

    分析:动态规划,f[i][j]表示长度为i的以第j个模式串为后缀的符合条件的串有多少个,f[i + 1][k] += f[i][j];

    k要符合第k个模式串可以由第j个模式串去掉首字母,再在结尾添加一个字母得到。就相当于我们不断的将模式串有重叠地(重叠长度为len-1)搭在当前构成的长度为i的串的结尾,使长度变为i+1。

    也就是第k个模式串就是长度为i+1的串比长度为i的串多出的那个长度为len的子串(长度为i+1的串的长度为len的子串个数只比长度为i的串的长度为len的子串个数多1)。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    using namespace std;
    
    #define maxn 605
    #define maxl 30
    #define maxm 105
    
    struct Edge
    {
        int next, v;
    }edge[maxn * maxn];
    
    int head[maxn];
    int comb_cnt, type_cnt, streamer_len;
    int comb_len;
    char comb[maxn][maxl];
    int ecount;
    int f[maxm][maxn];
    
    void input()
    {
        for (int i = 0; i < comb_cnt; i++)
            scanf("%s", comb[i]);
    }
    
    void addedge(int a, int b)
    {
        edge[ecount].v = b;
        edge[ecount].next = head[a];
        head[a] = ecount++;
    }
    
    bool connect1(char *a, char *b)
    {
        for (int i = 1; i < comb_len; i++)
            if (a[i] != b[i - 1])
                return false;
        return true;
    }
    
    void make()
    {
        comb_len = strlen(comb[0]);
        ecount = 0;
        memset(head, -1, sizeof(head));
        for (int i = 0; i < comb_cnt; i++)
            for (int j = 0; j < comb_cnt; j++)
                if (connect1(comb[i], comb[j]))
                    addedge(i, j);
    }
    
    void work()
    {
        memset(f, 0, sizeof(f));
        for (int i = 0; i < comb_cnt; i++)
            f[comb_len][i] = 1;
        for (int i = comb_len; i < streamer_len; i++)
            for (int j = 0; j < comb_cnt; j++)
                for (int k = head[j]; k != -1; k = edge[k].next)
                    f[i + 1][edge[k].v] += f[i][j];
        int ans = 0;
        for (int i = 0; i < comb_cnt; i++)
            ans += f[streamer_len][i];
        printf("%d\n", ans);
    }
    
    int main()
    {
        while (scanf("%d%d%d", &type_cnt, &streamer_len, &comb_cnt), type_cnt | streamer_len | comb_cnt)
        {
            input();
            make();
            work();
        }
        return 0;
    }
    View Code
  • 相关阅读:
    ORM 实现数据库表的增删改查
    数据库表设计(一对多,多对多)
    Razor模板引擎
    文件的上传(表单上传和ajax文件异步上传)
    生成验证码封装(新版)
    MD5加密
    反射的一些基本用法
    数据的增删改查(三层)<!--待补充-->
    linux文件的硬连接和软连接
    linux磁盘用满的两种情况
  • 原文地址:https://www.cnblogs.com/rainydays/p/3114060.html
Copyright © 2020-2023  润新知