HDU - 3341 Lost's revenge(AC自己主动机+DP)
Description
field of number theory. So Lost had never won the game. He was so ashamed and angry, but he didn't know how to improve his level of number theory.
One noon, when Lost was lying on the bed, the Spring Brother poster on the wall(Lost is a believer of Spring Brother) said hello to him! Spring Brother said, "I'm Spring Brother, and I saw AekdyCoin shames you again and again. I can't bear my believers were
being bullied. Now, I give you a chance to rearrange your gene sequences to defeat AekdyCoin!".
It's soooo crazy and unbelievable to rearrange the gene sequences, but Lost has no choice. He knows some genes called "number theory gene" will affect one "level of number theory". And two of the same kind of gene in different position in the gene sequences
will affect two "level of number theory", even though they overlap each other. There is nothing but revenge in his mind. So he needs you help to calculate the most "level of number theory" after rearrangement.
Input
For each testcase, first line is number of "number theory gene" N(1<=N<=50). N=0 denotes the end of the input file.
Next N lines means the "number theory gene", and the length of every "number theory gene" is no more than 10.
The last line is Lost's gene sequences, its length is also less or equal 40.
All genes and gene sequences are only contains capital letter ACGT.
Output
Sample Input
3
AC
CG
GT
CGAT
1
AA
AAA
0
Sample Output
Case 1: 3
Case 2: 2
题意:给你n个子串和一个母串,让你重排母串最多能得到多少个子串。
思路:如果ACGT的个数依次是num[0],num[1],num[2],num[3],将这四个数压缩成一个数,降低内存,然后动归dp[i][status]表示到自己主动机上i状态此时ACGT个数的状态时的最少
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int inf = 0x3f3f3f3f; struct Trie {
int nxt[510][4], fail[510], end[510];
int root, cnt; int newNode() {
for (int i = 0; i < 4; i++)
nxt[cnt][i] = -1;
end[cnt++] = 0;
return cnt - 1;
}
void init() {
cnt = 0;
root = newNode();
}
int getch(char ch) {
if (ch == 'A') return 0;
else if (ch == 'C') return 1;
else if (ch == 'G') return 2;
return 3;
}
void insert(char str[]) {
int len = strlen(str);
int now = root;
for (int i = 0; i < len; i++) {
if (nxt[now][getch(str[i])] == -1)
nxt[now][getch(str[i])] = newNode();
now = nxt[now][getch(str[i])];
}
end[now]++;
}
void build() {
queue<int> q;
fail[root] = root;
for (int i = 0; i < 4; i++) {
if (nxt[root][i] == -1)
nxt[root][i] = root;
else {
fail[nxt[root][i]] = root;
q.push(nxt[root][i]);
}
} while (!q.empty()) {
int now = q.front();
q.pop();
end[now] += end[fail[now]]; //好像每次都是这里
for (int i = 0; i < 4; i++) {
if (nxt[now][i] == -1)
nxt[now][i] = nxt[fail[now]][i];
else {
fail[nxt[now][i]] = nxt[fail[now]][i];
q.push(nxt[now][i]);
}
}
}
}
int dp[510][11*11*11*11+5];
int bit[4], num[4];
int solve(char str[]) {
int len = strlen(str);
memset(num, 0, sizeof(num));
for (int i = 0; i < len; i++)
num[getch(str[i])]++;
bit[0] = (num[1]+1) * (num[2]+1) * (num[3]+1);
bit[1] = (num[2]+1) * (num[3]+1);
bit[2] = (num[3]+1);
bit[3] = 1;
memset(dp, -1, sizeof(dp));
dp[root][0] = 0;
for (int A = 0; A <= num[0]; A++)
for (int B = 0; B <= num[1]; B++)
for (int C = 0; C <= num[2]; C++)
for (int D = 0; D <= num[3]; D++) {
int s = A * bit[0] + B * bit[1] + C * bit[2] + D * bit[3];
for (int i = 0; i < cnt; i++)
if (dp[i][s] >= 0) {
for (int k = 0; k < 4; k++) {
if (k == 0 && A == num[0]) continue;
if (k == 1 && B == num[1]) continue;
if (k == 2 && C == num[2]) continue;
if (k == 3 && D == num[3]) continue;
dp[nxt[i][k]][s+bit[k]] = max(dp[nxt[i][k]][s+bit[k]], dp[i][s]+end[nxt[i][k]]);
}
}
} int ans = 0;
int status = num[0] * bit[0] + num[1] * bit[1] + num[2] * bit[2] + num[3] * bit[3];
for (int i = 0; i < cnt; i++)
ans = max(ans, dp[i][status]);
return ans;
}
} ac;
char str[50]; int main() {
int n, cas = 1;
while (scanf("%d", &n) != EOF && n) {
ac.init();
for (int i = 0; i < n; i++) {
scanf("%s", str);
ac.insert(str);
} ac.build();
scanf("%s", str);
printf("Case %d: %d\n", cas++, ac.solve(str));
}
return 0;
}
HDU - 3341 Lost's revenge(AC自己主动机+DP)的更多相关文章
- Hdu 3341 Lost's revenge (ac+自己主动机dp+hash)
标题效果: 举个很多种DNA弦,每个字符串值值至1.最后,一个长字符串.要安排你最后一次另一个字符串,使其没事子值和最大. IDEAS: 首先easy我们的想法是想搜索的!管她3721..直接一个字符 ...
- HDU - 2825 Wireless Password(AC自己主动机+DP)
Description Liyuan lives in a old apartment. One day, he suddenly found that there was a wireless ne ...
- HDU - 4758 Walk Through Squares (AC自己主动机+DP)
Description On the beaming day of 60th anniversary of NJUST, as a military college which was Secon ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- hdu4758 Walk Through Squares (AC自己主动机+DP)
Walk Through Squares Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others ...
- poj 3691 DNA repair(AC自己主动机+dp)
DNA repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 5877 Accepted: 2760 Descri ...
- hdu4057 Rescue the Rabbit(AC自己主动机+DP)
Rescue the Rabbit Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU - 4511 小明系列故事――女友的考验(AC自己主动机+DP)
Description 最终放寒假了,小明要和女朋友一起去看电影.这天,女朋友想给小明一个考验,在小明正准备出发的时候.女朋友告诉他.她在电影院等他,小明过来的路线必须满足给定的规则: 1.如果小明 ...
- Hdu 2457 DNA repair (ac自己主动机+dp)
题目大意: 改动文本串的上的字符,使之不出现上面出现的串.问最少改动多少个. 思路分析: dp[i][j]表示如今 i 个字符改变成了字典树上的 j 节点. 然后顺着自己主动机一直转移方程. 注意合法 ...
随机推荐
- 13.2 UPDATE
13.2 UPDATE正在更新内容.请稍后
- sdut 2805(最小生成树)
大家快来A水题 Time Limit: 1000MS Memory limit: 65536K 题目描写叙述 (1<= N <=2000)(1<= M <= N*(N-1)/2 ...
- tomcat指定配置文件路径方法
1.在catalina.sh 中设置JAVA_OPTS,例如: JAVA_OPTS='-server -Xms1024m -Xmx1024m -XX:NewSize=128m -XX:MaxPermS ...
- Linux / Windows应用方案不完全对照表
Linux/Windows应用方案不完全对照表 650) this.width=650;" border="0" src="http://img1.51cto. ...
- c#数据类型格式转换大全
来源:网络 1.DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 1.1 取当前年月日时分秒 ...
- postgresql sql语句 更改表名
SELECT'alter table "public"."'|| t.tablename||'"'||' rename to "'|| "l ...
- Centos 7 JDK验证 解决java -version 报错: bash: /home/jdk1.8.0_161/bin/java: Permission denied
2.vim /etc/profile 编辑profile 文件,在里面添加: #set java enviroment JAVA_HOME=/usr/java/jdk1.8.0_144 JRE_H ...
- ipcalcIP地址计算
ipcalc命令是一个简单的ip地址计算器,可以完成简单的IP地址计算任务. 语法 ipcalc(选项) 选项 -b:由给定的IP地址和网络掩码计算出广播地址: -h:显示给定UP地址所对应的主机名: ...
- 【2017 Multi-University Training Contest - Team 5】Rikka with Graph
[Link]:http://acm.hdu.edu.cn/showproblem.php?pid=6090 [Description] 给你n个点; 让你在这n个点上最多连m条无向边; 使得 ∑ni= ...
- Spring 实现数据库读写分离(转)
现在大型的电子商务系统,在数据库层面大都采用读写分离技术,就是一个Master数据库,多个Slave数据库.Master库负责数据更新和实时数据查询,Slave库当然负责非实时数据查询.因为在实际的应 ...