hdu 3341 Lost's revenge
2013-05-18 11:34
232 查看
hdu 3341 Lost's revenge
题意:给出n个子串,和一个母串。问用母串中的字符最多可以组合出几个子串。可以重叠
最裸的是用dp[i][a][b][c][d]表示走到i号节点,用了a个'A' b个'G' c个'C' d个'T',但是这样开不下,用状态压缩,把a,b,c,d压缩成一维,因为总数只有40个,所以压缩后,状态不会很大,开个15555就可以过了。
题意:给出n个子串,和一个母串。问用母串中的字符最多可以组合出几个子串。可以重叠
最裸的是用dp[i][a][b][c][d]表示走到i号节点,用了a个'A' b个'G' c个'C' d个'T',但是这样开不下,用状态压缩,把a,b,c,d压缩成一维,因为总数只有40个,所以压缩后,状态不会很大,开个15555就可以过了。
#include<stdio.h> #include<string.h> #include<algorithm> #include<queue> using namespace std ; const int maxn = 555 ; int dp[maxn][22222] ; int len , cnt[4] , g[4] ; const int inf = 11111111 ; int T ; int get_k ( char v ) { int k ; switch ( v ) { case 'A' : k = 0 ; break ; case 'G' : k = 1 ; break ; case 'C' : k = 2 ; break ; case 'T' : k = 3 ; break ; } return k ; } void init () { T = 1 ; int i , j , k , l ; for ( i = 0 ; i < 4 ; i ++ ) { T *= ( cnt[i] + 1 ) ; } g[0] = 1 ; for ( i = 1 ; i < 4 ; i ++ ) g[i] = g[i-1] * ( cnt[i-1] + 1 ) ; } class AC_auto { private : int tot ; int c[4][maxn] ; int id[maxn] ; int fail[maxn] ; queue<int> q ; public : int new_node () { int i ; id[tot] = 0 ; fail[tot] = 0 ; for ( i = 0 ; i < 4 ; i ++ ) c[i][tot] = 0 ; return tot ++ ; } void init () { while ( !q.empty () ) q.pop () ; tot = 0 ; new_node () ; } void insert ( char *s ) { int now = 0 ; for ( ; *s ; s ++ ) { int k = get_k ( *s ) ; if ( !c[k][now] ) c[k][now] = new_node () ; now = c[k][now] ; } id[now] ++ ; } void get_fail () { int i , j , u = 0 ; for ( i = 0 ; i < 4 ; i ++ ) if ( c[i][u] ) q.push ( c[i][u] ) ; while ( !q.empty () ) { u = q.front () ; q.pop () ; for ( i = 0 ; i < 4 ; i ++ ) { if ( !c[i][u] ) { c[i][u] = c[i][fail[u]] ; continue ; } int e = c[i][u] ; j = fail[u] ; fail[e] = c[i][j] ; id[e] += id[fail[e]] ; q.push ( e ) ; } } } void work () { int i , j , k , l , t , f ; for ( i = 0 ; i <= tot ; i ++ ) for ( j = 0 ; j <= T ; j ++ ) dp[i][j] = -inf ; dp[0][0] = 0 ; for ( i = 0 ; i < T ; i ++ ) { for ( t = 0 ; t < tot ; t ++ ) { if ( dp[t][i] == -inf ) continue ; int u = i ; for ( f = 0 ; f < 4 ; f ++ ) { int p = u % ( cnt[f] + 1 ) ; u = u / ( cnt[f] + 1 ) ; if ( p == cnt[f] ) continue ; int e = i + g[f] ; int v = c[f][t] ; dp[v][e] = max ( dp[v][e] , dp[t][i] + id[v] ) ; } } } int ans = 0 ; for ( i = 0 ; i < tot ; i ++ ) ans = max ( ans , dp[i][T-1] ) ; printf ( "%d\n" , ans ) ; } } ac ; char s[55] ; int main () { int n , i , j ; int cas = 0 ; while ( scanf ( "%d" , &n ) != EOF ) { if ( n == 0 ) break ; cas ++ ; ac.init () ; for ( i = 1 ; i <= n ; i ++ ) { scanf ( "%s" , s ) ; ac.insert ( s ) ; } ac.get_fail () ; for ( i = 0 ; i < 4 ; i ++ ) cnt[i] = 0 ; scanf ( "%s" , s ) ; len = strlen ( s ) ; for ( i = 0 ; i < len ; i ++ ) { int k = get_k ( s[i] ) ; cnt[k] ++ ; } init () ; printf ( "Case %d: " , cas ) ; ac.work () ; } } /* 5 AATCATTGCT TATC TCCAG CT TATCCATGG TTAAAGAAAT 0 2 ATCCGG CCGTCAGGG GATGGAATGTGAACTGACTAGTTTGTTTCCCCC 3 */
相关文章推荐
- HDU 3341 Lost's revenge
- hdu 3341 Lost's revenge(dp+Ac自动机)
- hdu 3341 Lost's revenge
- [AC自动机+dp+变进制状压] hdu 3341 Lost's revenge
- HDU - 3341 Lost's revenge(AC自动机+DP)
- hdu 3341 Lost's revenge(AC自动机+DP)
- HDU - 3341 Lost's revenge(AC自己主动机+DP)
- HDU 3341 Lost's revenge
- HDU 3341 Lost's revenge(AC自动机+DP)
- Hdu 3341 Lost's revenge (ac自动机+dp+hash)
- HDU 3341 Lost's revenge(AC自动机+状态压缩DP)
- 【HDU】3341 Lost's revenge AC自动机+变进制+DP
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
- 【AC自动机】 HDOJ 3341 Lost's revenge
- hdu 3341 Lost's revenge(AC自动机+变进制状压DP)
- HDU 3341 Lost's revenge (AC自动机 + dp[优化好多= =])
- hdu 3341 Lost's revenge
- HDU 3341 Lost's revenge(AC自动机+DP+变进制优化)
- HDU 3341 Lost's revenge AC自动机 + 变进制状压DP
- HDU 5093 -- Battle ships【二分图最大匹配 && 经典建图】