Wireless Password [ 2009 Multi-University Training Contest 1 - Host by TJU ]
2011-08-03 22:38
453 查看
链接: http://acm.hdu.edu.cn/showproblem.php?pid=2825
分类: AC自动机 + 状态压缩 + DP
题意:问构成长度为 N 的字符串中包含已知串中至少 K 个的总个数
分析:
AC自动机部分:采用朴素的构建即可,注意记录当前节点的状态(status)即到达当前节点时包含的已知串状态
状态压缩部分:采用位存储当前节点包含已知串状态,第 i 位为1,表示包含第 i 个字符串
DP部分:建立dp[ i ][ j ][ k ],表示长度为 i,状态到达第 j 个结点,且包含已知串状态为 k 时的个数,显然有 dp[ 0 ][ 0 ][ 0 ] = 1,最后的结果是 ans = sum{ dp[ N ][ j ][ k ] | Ones( k ) >= K },其中Ones( k )表示 k 的二进制数中包含 1 的个数。
假设处理长度为i,当前结点为 j,且包含已知串状态为 k,且即将转移到某一结点指针 p,那么有
dp[ i ][ p->idx ][ p->status | k ] = dp[ i ][ p->idx ][ p->status | k ] + dp[ i - 1 ][ j ][ k ]
参考程序
分类: AC自动机 + 状态压缩 + DP
题意:问构成长度为 N 的字符串中包含已知串中至少 K 个的总个数
分析:
AC自动机部分:采用朴素的构建即可,注意记录当前节点的状态(status)即到达当前节点时包含的已知串状态
状态压缩部分:采用位存储当前节点包含已知串状态,第 i 位为1,表示包含第 i 个字符串
DP部分:建立dp[ i ][ j ][ k ],表示长度为 i,状态到达第 j 个结点,且包含已知串状态为 k 时的个数,显然有 dp[ 0 ][ 0 ][ 0 ] = 1,最后的结果是 ans = sum{ dp[ N ][ j ][ k ] | Ones( k ) >= K },其中Ones( k )表示 k 的二进制数中包含 1 的个数。
假设处理长度为i,当前结点为 j,且包含已知串状态为 k,且即将转移到某一结点指针 p,那么有
dp[ i ][ p->idx ][ p->status | k ] = dp[ i ][ p->idx ][ p->status | k ] + dp[ i - 1 ][ j ][ k ]
参考程序
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; typedef long long i64d; const int MOD = 20090717; const int maxQ = 10086; const int maxC = 26; const int maxE = 1024; const int maxS = 1024; const int maxN = 30; struct node { node *fal, *cld[maxC]; int status, idx; }; static node *Q[maxQ]; static int Qs, Qt; static node E[maxE]; static int nE; static node *root; inline void init() { nE = -1; root = &E[++nE]; root->status = 0, root->idx = 0; root->fal = 0; memset(root->cld, 0, sizeof(root->cld)); } inline void insert(char str[], int idx) { static int pos; static node *curNode; curNode = root; for(int i = 0; str[i]; ++i) { pos = str[i] - 'a'; if( curNode->cld[pos] != 0) curNode = curNode->cld[pos]; else { curNode->cld[pos] = &E[++nE]; curNode = curNode->cld[pos]; curNode->fal = 0; memset(curNode->cld, 0, sizeof(curNode->cld)); curNode->status = 0, curNode->idx = nE; } } curNode->status |= (0x1 << idx); } inline void acmation() { root->fal = 0; // root's fail static int pos; Qs = Qt = 0; Q[Qt++] = root; static node *cur; while( Qs != Qt ) { cur = Q[Qs++]; for(int i = 0; i < maxC; ++i) { pos = i; // change if possible if( cur->cld[pos] != 0 ) { if( cur == root ) cur->cld[pos]->fal = root; else { cur->cld[pos]->fal = cur->fal->cld[pos]; cur->cld[pos]->status |= cur->cld[pos]->fal->status; } Q[Qt++] = cur->cld[pos]; } else { if( cur == root ) cur->cld[pos] = root; else cur->cld[pos] = cur->fal->cld[pos]; } } } } static int N, M, K; static char subString[30]; static int dp[maxN][maxE][maxS]; static int Ones[maxS]; inline void getOnes() { static int val; for(int i = 0; i < maxS; ++i) { Ones[i] = 0; val = i; while( val ) ++Ones[i], val &= (val - 1); } } int main() { //freopen("data.in", "r", stdin); getOnes(); while( scanf("%d %d %d", &N, &M, &K) == 3 ) { if( N == 0 && M == 0 && K == 0 ) break; init(); for(int i = 0; i < M; ++i) { scanf("%s", subString); insert(subString, i); } acmation(); for(int i = 0; i <= N; ++i) { for(int j = 0; j <= nE; ++j) { for(int k = 0; k < (0x1 << M); ++k) { dp[i][j][k] = 0; } } } dp[0][0][0] = 1; static int nC; static node *p; for(int i = 1; i <= N; ++i) { for(int j = 0; j <= nE; ++j) { for(int k = 0; k < (0x1 << M); ++k) { if( dp[i - 1][j][k] != 0 ) { for(nC = 0; nC < maxC; ++nC) { p = E[j].cld[nC]; dp[i][p->idx][k | p->status] += dp[i - 1][j][k]; dp[i][p->idx][k | p->status] %= MOD; } } } } } int ans = 0; for(int j = 0; j <= nE; ++j) { for(int k = 0; k < (0x1 << M); ++k) { if( Ones[k] < K ) continue; ans += dp [j][k]; ans %= MOD; } } printf("%d\n", ans); } return 0; }
相关文章推荐
- 2009 Multi-University Training Contest 1 - Host by TJU
- 2009 Multi-University Training Contest 4 - Host by HDU
- 2009 Multi-University Training Contest 8 - Host by BJNU
- 2009 Multi-University Training Contest 5 - Host by NUDT
- hdu 3094 A tree game 2009 Multi-University Training Contest 18 - Host by ECNU
- HDU3996 Gold Mine最大权闭合图 2011 Multi-University Training Contest 16 - Host by TJU
- HDU 3015——Disharmony Trees(树状数组 2009 Multi-University Training Contest 12 - Host by FZU)
- Connections between cities&&2009 Multi-University Training Contest 8 - Host by BJNU
- HDU3998 Sequence 动态规划+最大流2011 Multi-University Training Contest 16 - Host by TJU
- 2009 Multi-University Training Contest 10 - Host by NIT
- hdu2888Check Corners【二维RMQ】2009 Multi-University Training Contest 9 - Host by HIT
- HDU 3920 Clear All of Them I 状态压缩DP 2011 Multi-University Training Contest 9 - Host by BJTU
- HDU 3879 Base Station 最大权闭包 2011 Multi-University Training Contest 5 - Host by BNU
- HDU HDU 3861 The King’s Problem 2011 Multi-University Training Contest 3 - Host by BIT
- HDU 3874 Necklace 2011 Multi-University Training Contest 4 - Host by SDU 树状数组+离散化
- 【转】2011 Multi-University Training Contest 3 - Host by BIT
- Hdu 3936 FIB Query[矩阵快速幂](2011 Multi-University Training Contest 10 - Host by HRBEU)
- 2011 Multi-University Training Contest 1 - Host by HNU&&Cat VS Dog
- Moonfang's Birthday&&2011 Multi-University Training Contest 3 - Host by BIT
- HDU 3873 Invade the Mars 2011 Multi-University Training Contest 4 - Host by SDU