1 条题解

  • 0
    @ 2025-5-12 18:44:36

    弗里兰语安全句子计数问题题解

    这个问题涉及到字符串匹配、自动机和动态规划的综合应用,主要考察AC自动机和状态转移的思想。

    问题分析

    问题描述: 给定一个包含N个字符的字母表和P个被禁止的单词,计算长度为M的句子中不包含任何禁止单词的数量。

    关键思路

    1. 使用AC自动机预处理所有禁止单词
    2. 利用动态规划在AC自动机上进行状态转移
    3. 处理大数计算问题,确保结果正确

    解题思路

    1. AC自动机构建

      • 将所有禁止单词插入到Trie树中
      • 构建失败指针,使自动机能够在匹配失败时跳转至正确位置
      • 标记所有包含禁止单词的节点
    2. 动态规划状态转移

      • 状态定义:f[i][j] 表示长度为i的字符串,当前在AC自动机的节点j的安全句子数量
      • 状态转移:对于每个节点和每个可能的字符,检查转移后的节点是否包含禁止单词
      • 初始状态:f[0][root] = 1
      • 结果:所有长度为M且不包含禁止单词的节点的状态之和
    3. 大数处理

      • 由于结果可能非常大,使用自定义的大整数类进行计算
      • 实现大整数的加法和输出功能

    代码实现分析

    AC自动机部分

    struct Tree {
        int child[305], fail, flag;
        void clear() {
            memset(child, 0, sizeof(child));
            fail = 0;
            flag = 0;
        }
    };
    
    struct Aho_Corasick_Automaton {
        int cnt;
        Tree tree[maxn];
        
        void init() {
            cnt = 1;
            memset(tree, 0, sizeof(tree));
        }
        
        void insert(char s[]) {
            // 将禁止单词插入Trie树
        }
        
        void buildfail() {
            // BFS构建失败指针
        }
    };
    

    动态规划部分

    BigInteger f[105][305], ans = 0;
    
    // 初始化
    f[0][1] = 1;
    
    // 动态规划状态转移
    for(int i = 1; i <= m; i++) {
        for(int j = 1; j <= ac.cnt; j++) {
            if(ac.tree[j].flag) continue; // 跳过包含禁止单词的节点
            for(int k = 0; k < n; k++) {
                if(ac.tree[ac.tree[j].child[k]].flag) continue; // 转移后节点包含禁止单词
                f[i][ac.tree[j].child[k]] += f[i-1][j];
            }
        }
    }
    
    // 计算结果
    for(int i = 1; i <= ac.cnt; i++)
        if(!ac.tree[i].flag) ans += f[m][i];
    

    大整数类部分

    struct BigInteger {
        static const int BASE = 10000;
        static const int WIDTH = 4;
        vector<int> s;
        
        // 构造函数和赋值运算符
        // 加法运算符重载
        // 输出运算符重载
    };
    

    复杂度分析

    • 时间复杂度O(M×C×N)O(M \times C \times N),其中C是AC自动机的节点数,N是字母表大小。
    • 空间复杂度O(C+M×C)O(C + M \times C),主要用于存储AC自动机和动态规划数组。
    • 1

    信息

    ID
    626
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者