「Bzoj 1212」「HNOI2004」L语言 (Trie + 存在性DP)

Bzoj 1212
题意:一段文章$T$是由若干小写字母构成。一个单词$W$也是由若干小写字母构成。一个字典$D$是若干个单词的集合。我们称一段文章T在某个字典$D$下是可以被理解的,是指如果文章$T$可以被分成若干部分,且每一个部分都是字典$D$中的单词。给定一个字典$D$,你的程序需要判断若干段文章在字典$D$下是否能够被理解。并给出其在字典$D$下能够被理解的最长前缀的位置。

容易发现若一个串$S$能被理解,那么$S+D_i$也能理解
那么我们就可以做一个存在性DP,按上面的来转移
我们发现单词长度不超过10,那么我们将单词插进Trie树,树高最高为10,那么直接暴力转移即可。具体可以看代码实现。

知识点:
1、数据范围小一定要重视
2、思路想好再写,不要贪快

#include<cstdio> 
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#define ms(i, j) memset(i, j, sizeof i)
#define LL long long
#define db long double
#define fir first
#define sec second
#define mp make_pair
using namespace std;

namespace flyinthesky {

    const int MAXN = 205;

    int ch[MAXN][27], val[MAXN], sz, dp[1000000 + 5];
    int n, m;
    char s[1000000 + 5];

    void insert() {
        int len = strlen(s), now = 0;
        for (int i = 0; i < len; ++i) {
            int c = s[i] - 'a';
            if (!ch[now][c]) ch[now][c] = ++sz;
            now = ch[now][c];
            if (i == len - 1) val[now] = 1;
        }
    }
    int pro(int ith) {
        dp[0] = ith;
        int len = strlen(s + 1), ans = 0;
        for (int i = 0; i <= len; ++i) {
            if (dp[i] != ith) continue ; else ans = i;
            int now = 0;
            for (int j = i + 1; j <= len; ++j) {
                int c = s[j] - 'a';
                if (!ch[now][c]) break ;
                now = ch[now][c];
                if (val[now]) dp[j] = ith;
            }
        }
        return ans;
    }

    void clean() {
        ms(dp, 0), ms(ch, 0), ms(val, 0), sz = 0;
    }
    int solve() {

        clean();
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) scanf("%s", s), insert();

        for (int i = 1; i <= m; ++i) {
            scanf("%s", s + 1);
            printf("%d\n", pro(i));
        }

        return 0;
    }
}
int main() { 
    flyinthesky::solve();
    return 0;
}
/*
4 3 
is
name
what
your
whatisyouname
whatisyourname
whaisyourname

2 10
abc
bc

abcab


3 10
abcdefg
cde

5 10
abc
aba
c
bcbac
a

abacabcbacababcbacbcbbb

*/
------ 本文结束 ------