首页 > 编程语言 > 详细

[HNOI2004]L语言 (Trie树+dp)

时间:2018-12-03 22:33:32      阅读:179      评论:0      收藏:0      [点我收藏+]

[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) ;
    }
}

 

[HNOI2004]L语言 (Trie树+dp)

原文:https://www.cnblogs.com/harryhqg/p/10061298.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!