首页 > 代码库 > HDU 2296 Ring AC自动机 + DP
HDU 2296 Ring AC自动机 + DP
题意:给你n个模式串,每个模式串有一个得分,让你构造出一个长度为N之内且分数最高的文本串;输出字典序列最小的。
解题思路: AC自动机 + DP , 不过要输出字典序列最小,多开一个 一个三维字符串来辅助二维DP(新思路) , DP[i][j] ,表示到i位置状态为j的最大得分。
解题代码:
1 // File Name: temp.cpp 2 // Author: darkdream 3 // Created Time: 2014年09月11日 星期四 15时18分4秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #include<queue> 25 #define LL long long 26 #define maxn 20000 27 using namespace std; 28 29 int n,m; 30 char str[55][1110][55]; 31 struct Trie 32 { 33 int next[maxn][26],fail[maxn],end[maxn]; 34 int root,L; 35 int newnode() 36 { 37 memset(next[L],-1,sizeof(next[L])); 38 end[L++] = 0; 39 return L-1; 40 } 41 void init() 42 { 43 L = 0; 44 root = newnode(); 45 } 46 void insert(char buf[],int id) 47 { 48 int len = strlen(buf); 49 int now = root; 50 for(int i = 0;i < len ;i++) 51 { 52 if(next[now][buf[i]-‘a‘] == -1) 53 { 54 next[now][buf[i]-‘a‘] = newnode(); 55 } 56 now = next[now][buf[i]-‘a‘]; 57 } 58 end[now] = id; 59 } 60 void build() 61 { 62 queue<int>Q; 63 fail[root] = root; 64 for(int i = 0;i < 26;i++) 65 if(next[root][i] == -1) 66 next[root][i] = root; 67 else 68 { 69 fail[next[root][i]] = root; 70 Q.push(next[root][i]); 71 } 72 while( !Q.empty() ) 73 { 74 int now = Q.front(); 75 Q.pop(); 76 if(end[fail[now]] == -1)end[now] = -1; 77 else end[now] |= end[fail[now]]; 78 for(int i = 0;i < 26;i++) 79 if(next[now][i] == -1) 80 next[now][i] = next[fail[now]][i]; 81 else 82 { 83 fail[next[now][i]] = next[fail[now]][i]; 84 Q.push(next[now][i]); 85 } 86 } 87 } 88 int cmp(char str1[],char str2[]) 89 { 90 if(strlen(str1) < strlen(str2)) 91 { 92 return 1; 93 }else if(strlen(str1) > strlen(str2)){ 94 return 0 ; 95 }else{ 96 if(strcmp(str1,str2) < 0) 97 return 1; 98 } 99 return 0;100 }101 int dp[100][maxn];102 void solve()103 {104 memset(dp,-1,sizeof(dp));105 dp[0][0] = 0 ; 106 int ai = 0 ; 107 int aj = 0 ;108 int mx = 0;109 char tmp[55];110 char ans[55];111 strcpy(ans,"");112 strcpy(str[0][0],"");113 for(int i = 0 ;i < n;i ++)114 {115 for(int j =0 ;j < L ;j ++)116 {117 if(dp[i][j] != -1 )118 {119 strcpy(tmp,str[i][j]);120 int len = strlen(str[i][j]);121 122 for(int s = 0 ;s < 26 ;s ++)123 {124 int nex = next[j][s];125 tmp[len] = ‘a‘ + s;126 tmp[len + 1] = 0;127 int tt = dp[i][j];128 129 if(end[nex] != -1)130 tt += end[nex];131 132 if(tt > dp[i+1][nex] ||(tt == dp[i+1][nex] && cmp(tmp,str[i+1][nex]) ))133 {134 dp[i+1][nex] = tt;135 strcpy(str[i+1][nex],tmp);136 if(tt > mx ||(tt == mx && cmp(tmp,ans)))137 {138 mx = tt; 139 strcpy(ans,tmp);140 //printf("%s %d\n",ans,mx);141 }142 }143 }144 }145 }146 }147 printf("%s\n",ans);148 }149 150 };151 152 Trie ac;153 char tstr[205][20];154 int main(){155 int t; 156 scanf("%d",&t);157 while(t--)158 {159 scanf("%d %d",&n,&m);160 ac.init();161 for(int i = 1;i <= m ;i ++ )162 {163 scanf("%s",tstr[i]);164 }165 int temp ; 166 for(int i = 1; i <= m;i ++)167 {168 scanf("%d",&temp);169 ac.insert(tstr[i],temp) ; 170 }171 ac.build();172 ac.solve();173 }174 return 0;175 }
HDU 2296 Ring AC自动机 + DP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。