#include<stdio.h> #include<string.h> #include<algorithm> #include<vector> #include<queue> using namespace std ; const int N = 51 ; const int maxn = 501 ; int dp[N][N][maxn] , inc[N][N][N] ; vector<int> vec[N][N] ; short add[12][N][maxn] , to[12][N][maxn] ; char s1[N][N] , s2[N][N] ; int n , m , l ; int len[N] ; struct AC_auto { int c[26][maxn] , tot , cnt[maxn] , fail[maxn] ; queue<int> Q ; int new_node () { int i ; for ( i = 0 ; i < 26 ; i ++ ) c[i][tot] = 0 ; fail[tot] = cnt[tot] = 0 ; return tot ++ ; } void insert ( char *s ) { int now = 0 ; for ( ; *s ; s ++ ) { int k = *s - ‘a‘ ; if ( !c[k][now] ) c[k][now] = new_node () ; now = c[k][now] ; } cnt[now] ++ ; } void get_fail () { int u = 0 , e , i , j ; for ( i = 0 ; i < 26 ; i ++ ) if ( c[i][u] ) Q.push ( c[i][u] ) ; while ( !Q.empty () ) { u = Q.front () ; Q.pop () ; for ( i = 0 ; i < 26 ; i ++ ) { if ( c[i][u] ) { e = c[i][u] ; j = fail[u] ; fail[e] = c[i][j] ; cnt[e] += cnt[fail[e]] ; Q.push ( e ) ; } else c[i][u] = c[i][fail[u]] ; } } } void work () { int i , j , k , t , now , s , v , x , p , q ; for ( i = 0 ; i <= 11 ; i ++ ) for ( k = 1 ; k <= n ; k ++ ) for ( t = 0 ; t < tot ; t ++ ) add[i][k][t] = 0 ; for ( i = 1 ; i <= n ; i ++ ) for ( k = 0 ; k < tot ; k ++ ) { for ( v = 1 ; v <= len[i] ; v ++ ) { now = k ; for ( x = v ; x <= len[i] ; x ++ ) { p = s1[i][x] - ‘a‘ ; now = c[p][now] ; add[v][i][k] += cnt[now] ; } to[v][i][k] = now ; } } for ( i = 0 ; i <= l ; i ++ ) for ( j = 1 ; j <= n ;j ++ ) for ( k = 0 ; k < tot ; k ++ ) dp[i][j][k] = -1111111 ; for ( i = 1 ; i <= n ; i ++ ) { if ( len[i] > l ) continue ; now = 0 ; x = 0 ; for ( j = 1 ; j <= len[i] ; j ++ ) { k = s1[i][j] - ‘a‘ ; now = c[k][now] ; x += cnt[now] ; } dp[len[i]][i][now] = x ; } for ( i = 0 ; i < l ; i ++ ) for ( j = 1 ; j <= n ; j ++ ) for ( k = 0 ; k < tot ; k ++ ) { if ( dp[i][j][k] == -1111111 ) continue ; for ( t = 1 ; t <= n ; t ++ ) { s = vec[j][t].size () ; for ( x = 0 ; x < s ; x ++ ) { v = vec[j][t][x] ; p = i + inc[j][t][v] ; if ( p > l ) continue ; q = to[v][t][k] ; dp[p][t][q] = max ( dp[p][t][q] , dp[i][j][k] + add[v][t][k] ) ; } } } int ans = 0 ; for ( i = 1 ; i <= l ; i ++ ) for ( j = 1 ; j <= n ; j ++ ) for ( k = 0 ; k < tot ; k ++ ) ans = max ( ans , dp[i][j][k] ) ; printf ( "%d\n" , ans ) ; } void init () { tot = 0 ; new_node () ; } } ac ; void init () { ac.init () ; int i , j , k , t , l1 , l2 , flag ; for ( i = 1 ; i <= m ; i ++ ) ac.insert ( s2[i] + 1 ) ; ac.get_fail () ; for ( i = 1 ; i <= n ; i ++ ) len[i] = strlen( s1[i] + 1 ) ; for ( i = 1 ; i <= n ; i ++ ) for ( j = 1 ; j <= n ; j ++ ) { vec[i][j].clear () ; l1 = len[i] ; l2 = len[j] ; vec[i][j].push_back ( 1 ) ; inc[i][j][1] = l2 ; for ( k = l1 ; k >= 2 ; k -- ) { if ( l1 - k + 1 >= l2 ) break ; flag = 1 ; for ( t = k ; t <= l1 ; t ++ ) if ( s1[i][t] != s1[j][t-k+1] ) { flag = 0 ; break ; } if ( flag ) { vec[i][j].push_back ( l1 - k + 2 ) ; inc[i][j][l1-k+2] = l2 - l1 + k - 1 ; } } } ac.work () ; } int main () { int i , j , k ; while ( scanf ( "%d%d%d" , &n , &m , &l ) != EOF ) { for ( i = 1 ; i <= n ; i ++ ) scanf ( "%s" , s1[i] + 1 ) ; for ( i = 1 ; i <= m ; i ++ ) scanf ( "%s" , s2[i] + 1 ) ; init () ; } }
zoj 3535 Gao the String II(ac自动机+dp),布布扣,bubuko.com
zoj 3535 Gao the String II(ac自动机+dp)
原文:http://blog.csdn.net/no__stop/article/details/23175555