HDU 3341 Lost's revenge AC自动机+ 状态压缩DP
2014-09-16 12:17
288 查看
题意:这个题目和HDU2457有点类似,都是AC自动机上的状态dp,题意就是给你只含有'A','T','C','G',四个字符的子串和文本串,问你文本串如何排列才可以使得文本串中包含有更多的模式串
解题思路:我们知道了 有 num[0] 个 'A', num[1] 个 ‘T’, num[2] 个 ‘C’,num[3] 个‘G’, 我们的可以知道暴力的思路就是把所有的文本串都枚举出来然后一一匹配。我们膜拜了一下春哥以后,就可以有以下思路: 把一个串的信息压缩一下,把具有同样个数字符的串看成是同一种情况 比如 AATCG 和 TCGAA 看成是同一种,然后就对不同情况在 AC自动机上的不同状态进行dp, dp[i][j], i表示 串压缩以后的 值 ,j 表示 i串现在在 AC自动机状态 j 上, dp[i][j] 表示 i 在j 上的最大值。
这里我们压缩有一种巧妙的方法 , 相当于进位制的压缩。
最后还有一种情况,,模板串可以相同 千万注意.
View Code
解题思路:我们知道了 有 num[0] 个 'A', num[1] 个 ‘T’, num[2] 个 ‘C’,num[3] 个‘G’, 我们的可以知道暴力的思路就是把所有的文本串都枚举出来然后一一匹配。我们膜拜了一下春哥以后,就可以有以下思路: 把一个串的信息压缩一下,把具有同样个数字符的串看成是同一种情况 比如 AATCG 和 TCGAA 看成是同一种,然后就对不同情况在 AC自动机上的不同状态进行dp, dp[i][j], i表示 串压缩以后的 值 ,j 表示 i串现在在 AC自动机状态 j 上, dp[i][j] 表示 i 在j 上的最大值。
这里我们压缩有一种巧妙的方法 , 相当于进位制的压缩。
最后还有一种情况,,模板串可以相同 千万注意.
// File Name: temp.cpp // Author: darkdream // Created Time: 2014年09月11日 星期四 15时18分4秒 #include<vector> #include<list> #include<map> #include<set> #include<deque> #include<stack> #include<bitset> #include<algorithm> #include<functional> #include<numeric> #include<utility> #include<sstream> #include<iostream> #include<iomanip> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<ctime> #include<queue> #define LL long long #define maxn 705 using namespace std; int dp[15000][505]; int num[6]; int adv[6]; struct Trie { int next[maxn][4],fail[maxn],end[maxn]; int root, L; int newnode() { memset(next[L],-1,sizeof(next[L])); end[L++] = 0 ; return L-1; } void init() { L = 0 ; root = newnode(); } void insert(int buf[],int len) { int now = root; for(int i = 0 ;i < len ;i ++) { if(next[now][buf[i]] == -1) { next[now][buf[i]] = newnode(); } now = next[now][buf[i]]; } end[now] ++; } void build() { queue<int> Q; fail[root] = root; for(int i = 0;i < 4;i ++) { if(next[root][i] == -1) { next[root][i] = root; //指向root 是没有问题的,我们主要是通过end 数组对个数进行计数的。 }else{ fail[next[root][i]] = root; Q.push(next[root][i]); } } while(!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0 ;i < 4;i ++) { if(next[now][i] == -1) { next[now][i] = next[fail[now]][i]; } else{ fail[next[now][i]] = next[fail[now]][i]; if(end[next[fail[now]][i]] != 0 ) end[next[now][i]] += end[fail[next[now][i]]]; // 计算 end 最多。 Q.push(next[now][i]); } } } } void query( int ca) { //end[3] = 1; memset(dp,-1,sizeof(dp)); dp[0][0] = 0; int ans = 0 ; int mx = num[0]*adv[0] + num[1]*adv[1] + num[2]*adv[2] + num[3]* adv[3]; for(int i = 0;i <= mx ;i ++ ) { int tnum[5]; int k = i ; for(int j = 0 ;j < 4 ;j ++) { tnum[j] = k / adv[j]; k = k %adv[j]; } for(int j = 0;j < L;j ++) { if(dp[i][j] != -1) { for(int s = 0 ;s < 4;s ++) { if(num[s] - tnum[s] > 0 ) { dp[i+adv[s]][next[j][s]] = max(dp[i+ adv[s]][next[j][s]] ,dp[i][j] + end[next[j][s]]); } } } // printf("%d ",dp[i][j]); } //printf("\n"); } for(int i = 0 ;i < L ;i ++) ans = max(dp[mx][i],ans); printf("Case %d: %d\n",ca,ans); } }; char buf[3000]; int temp[3000]; Trie ac; void change(int len) { for(int i = 0;i < len;i ++) { if(buf[i] == 'A') { temp[i] = 0 ; }else if(buf[i] == 'T'){ temp[i] = 1; }else if(buf[i] == 'G') { temp[i] = 2; }else if(buf[i] == 'C') { temp[i] = 3; } } } int main(){ int n; int ca= 0 ; //freopen("in","r",stdin); while(scanf("%d",&n) != EOF,n) { ca ++ ; ac.init(); int len; memset(num,0,sizeof(num)); for(int i =1 ;i <= n;i ++) { scanf("%s",buf); len = strlen(buf); change(len); ac.insert(temp,len); } ac.build(); scanf("%s",buf); len = strlen(buf); change(len); memset(num,0,sizeof(num)); for(int i = 0 ;i < len;i ++) num[temp[i]] ++ ; for(int i = 0 ;i < 4;i ++) { adv[i] = 1 ; for(int j = i+1;j < 4;j ++) { adv[i] *= (num[j]+1) ; } // printf("%d ",adv[i]); } //printf("\n"); ac.query(ca); } return 0; }
View Code
相关文章推荐
- HDU 4049 Tourism Planning 状态压缩(DP)
- HDU 1074 状态压缩DP
- hdu 4317 Unfair Nim (状态压缩DP) 【2012 Multi-University Training Contest 2】
- Hdu 4057 Rescue the Rabbit (AC自动机+状态压缩dp) - 2011 ACM-ICPC Dalian Regional Contest Problem G
- HDU 4336 Card Collector [状态压缩概率DP]
- hdu 1565 状态压缩DP
- hdu 4317 Unfair Nim(状态压缩DP)——2012 Multi-University Training Contest 2
- HDU_4317 Unfair Nim 状态压缩dp
- HDU 3811 DP状态压缩
- hdu 4385 Moving Bricks (状态压缩dp 2012 Multi-University Training Contest 9 )
- HDU 3920 Clear All of Them I 状态压缩DP 2011 Multi-University Training Contest 9 - Host by BJTU
- hdu 1565 状态压缩 dp
- HDU 3001 Travelling 【状态压缩DP】
- hdu 1074 DFS+状态压缩DP
- hdu 2809 God of War //状态压缩DP
- HDU 4049 状态压缩DP
- hdu 2167 状态压缩dp(入门题目)
- hdu 3811 用状态压缩DP 解决看似组合数学的题目
- HDU 3811 Permutation 记忆化搜索 状态压缩 DP
- hdu 1074 Doing Homework 状态压缩的DP