[HNOI2004]L语言 解题报告
这似乎是一道各种字符串算法的模板题,例如Trie树,AC自动机,甚至还有用KMP的,666
数据很水放了几个暴力的过了
dp当然也是很好想的
dp[i]表示字符串前i段是否能够被匹配
我们枚举一个k∈(0,j),如果前k段能够匹配到,那么我们只用考虑k+1到j这一段是否能够在字典里头查找到,
于是顺理成章想到字典树(基本操作不讲了)
转移方程:dp[i]|=dp[k]&find(k+1,i),即如果一个k可行,那么dp[i]就位true
那么问题就搞定啦
代码:
#include <bits/stdc++.h> using namespace std ; #define rep(i, a, b) for (int (i) = (a); (i) <= (b); (i)++) #define Rep(i, a, b) for (int (i) = (a) - 1; (i) < (b); (i)++) #define REP(i, a, b) for (int (i) = (a); (i) >= (b); (i)--) #define clr(a) memset(a, 0, sizeof(a)) #define Sort(a, len, cmp) sort(a + 1, a + len + 1, cmp) #define ass(a, sum) memset(a, sum, sizeof(a)) #define ls ((rt) << 1) #define rs ((rt) << 1 | 1) #define lowbit(x) (x & -x) #define mp make_pair #define pb push_back #define fi first #define se second #define endl ‘\n‘ #define ENDL cout << endl #define SZ(x) ((int)x.size()) typedef long long ll ; typedef unsigned long long ull ; typedef vector <int> vi ;const int N = 2000010 ; const int M = 210 ; const double eps = 1e-8 ; const int iinf = INT_MAX ; const ll linf = 2e18 ; const double dinf = 1e30 ; const int MOD = 1000000007 ; inline int read(){ int X = 0, w = 0 ; char ch = 0 ; while (!isdigit(ch)) { w |= ch == ‘-‘ ; ch = getchar() ; } while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar() ; return w ? - X : X ; } void write(int x){ if (x < 0) putchar(‘-‘), x = - x ; if (x > 9) write(x / 10) ; putchar(x % 10 + ‘0‘) ; } void print(int x) { cout << x << endl ; exit(0) ; } void PRINT(string x) { cout << x << endl ; exit(0) ; } void douout(double x){ printf("%lf\n", x + 0.0000000001) ; } int n, m, ans, len, id ; string s, str ; int dp[N], trie[M][26], val[M] ; void insert(string s) { len = max(len, SZ(s)) ; int now = 0 ; for (int i = 0; i < SZ(s); i++) { int c = s[i] - ‘a‘ ; if (!trie[now][c]) trie[now][c] = ++id ; now = trie[now][c] ; } val[now] = 1 ; } bool find(int s, int t) { int now = 0 ; for (int i = s; i <= t; i++) { int c = str[i] - ‘a‘ ; if (!trie[now][c]) return 0 ; now = trie[now][c] ; } return val[now] ; } signed main(){ scanf("%d%d", &n, &m) ; for (int i = 1; i <= n; i++) { cin >> s ; insert(s) ; } for (int i = 1; i <= m; i++) { cin >> str ; clr(dp) ; ans = 0 ; for (int j = 0; j < SZ(str); j++) for (int k = max(j - len, -1); k <= j; k++) if ((k == -1 || dp[k]) && find(k + 1, j)) { dp[j] = 1 ; ans = j + 1 ; break ; } printf("%d\n", ans) ; } }
原文:https://www.cnblogs.com/harryhqg/p/10061298.html