hdu3341Lost's revenge(ac自动机+dp)
类似的dp省赛时就做过了,不过这题卡内存,需要把当前状态hash一下,可以按进制来算出当前的状态,因为所有的状态数是不会超过10*10*10*10的,所以完全可以把这些存下来。
刚开始把trie的的遍历节点写在外层循环了,一直WA,后来想了一下,状态是只会向前走的,但是节点不一样,如果由 当前节点的状态-》下一节点的状态,下一节点有可能是在当前节点之前的,这样是不对的,所以需要由当前状态的节点 -》下一状态的节点 。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 510
#define LL long long
#define INF -1
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>;
const int child_num = ;
char vir[],s[];
int mp[];
class AC
{
private:
int ch[N][child_num];
int Q[N];
int fail[N];
int val[N];
int id[];
int sz;
int dp[N][];
public:
void init()
{
fail[] = ;
id['A'] = ,id['G'] = ,id['T'] = ,id['C'] = ;
}
void reset()
{
memset(ch[],,sizeof(ch[]));
memset(val,,sizeof(val));
sz = ;
}
void insert(char *a,int key)
{
int p = ;
for( ; *a ; a++)
{
int d = id[*a];
if(ch[p][d]==)
{
memset(ch[sz],,sizeof(ch[sz]));
ch[p][d] = sz++;
}
p = ch[p][d];
}
val[p] += key;
}
void construct()
{
int i,head=,tail = ;
for(i = ;i < child_num ; i++)
{
if(ch[][i])
{
fail[ch[][i]] = ;
Q[tail++] = ch[][i];
}
}
while(head!=tail)
{
int u = Q[head++];
val[u]+=val[fail[u]];
for(i = ; i < child_num ; i++)
{
if(ch[u][i])
{
fail[ch[u][i]] = ch[fail[u]][i];
Q[tail++] = ch[u][i];
}
else ch[u][i] = ch[fail[u]][i];
}
}
}
void work(char *s,int kk)
{
int k = strlen(s);
int num[]= {},pp[];
memset(num,,sizeof(num));
int o = ,i,j,g,e,z,y;
for(i = ; i < k ;i++)
{
num[id[s[i]]]++;
}
pp[] = ;
for(i = ; i <= ; i++)
pp[i] = pp[i-]*;
memset(mp,-,sizeof(mp));
for(i = ; i <= num[] ; i++)
for(j = ;j <= num[] ; j++)
for(g = ; g <= num[] ; g++)
for(e = ; e <= num[] ;e++)
{
int sum = e*pp[]+g*pp[]+j*+i;
o++;
mp[sum] = o;
}
memset(dp,-,sizeof(dp));
dp[][] = ;
for(i = ; i <= num[] ; i++)
for(j = ;j <= num[] ; j++)
for(g = ; g <= num[] ; g++)
for(e = ; e <= num[] ;e++)
{
for(z = ;z < sz ; z++)
{
int sum = e*pp[]+g*pp[]+j*+i;
if(dp[z][mp[sum]]==-) continue;
for(y = ; y < child_num ; y++)
{
int yy = ch[z][y];
int ss = pp[y]+sum;
if(mp[ss]==-) continue;
dp[yy][mp[ss]] = max(dp[yy][mp[ss]],dp[z][mp[sum]]+val[yy]);
}
}
}
int ans = ;
for(i = ;i < sz ; i++)
{
ans=max(dp[i][o],ans);
}
printf("Case %d: ",kk);
printf("%d\n",ans);
}
}ac;
int main()
{
int n,kk=;
ac.init();
while(scanf("%d",&n)&&n)
{
ac.reset();
kk++;
while(n--)
{
scanf("%s",vir);
ac.insert(vir,);
}
ac.construct();
scanf("%s",s);
ac.work(s,kk);
}
return ;
}
hdu3341Lost's revenge(ac自动机+dp)的更多相关文章
- HDU-3341-Lost's revenge(AC自动机, DP, 压缩)
链接: https://vjudge.net/problem/HDU-3341 题意: Lost and AekdyCoin are friends. They always play "n ...
- HDU 3341 Lost's revenge AC自动机+dp
Lost's revenge Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)T ...
- hdu3341Lost's revenge (AC自动机+变进制dp)
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submissio ...
- HDU3341 Lost's revenge(AC自动机&&dp)
一看到ACGT就会想起AC自动机上的dp,这种奇怪的联想可能是源于某道叫DNA什么的题的. 题意,给你很多个长度不大于10的小串,小串最多有50个,然后有一个长度<40的串,然后让你将这个这个长 ...
- POJ1625 Censored!(AC自动机+DP)
题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...
- HDU2296 Ring(AC自动机+DP)
题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...
- HDU2457 DNA repair(AC自动机+DP)
题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...
- hdu 4117 GRE Words AC自动机DP
题目:给出n个串,问最多能够选出多少个串,使得前面串是后面串的子串(按照输入顺序) 分析: 其实这题是这题SPOJ 7758. Growing Strings AC自动机DP的进阶版本,主题思想差不多 ...
- hdu 2457(ac自动机+dp)
题意:容易理解... 分析:这是一道比较简单的ac自动机+dp的题了,直接上代码. 代码实现: #include<stdio.h> #include<string.h> #in ...
随机推荐
- INSTRUCTION CYCLE
COMPUTER ORGANIZATION AND ARCHITECTURE DESIGNING FOR PERFORMANCE NINTH EDITION • Fetch: Read the nex ...
- 《Linux内核分析》第一周 计算机是如何工作的?
刘蔚然 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000] WEEK ONE(2. ...
- 转:"在已损坏了程序内部状态的XXX.exe 中发生了缓冲区溢出"的一种可能原因
我的问题跟原作者的问题差不多.头文件和DLL不匹配导致的. 原文链接:http://blog.csdn.net/u012494876/article/details/39030887 今天软件突然出现 ...
- windows系统调用 获取当前内存信息
#include "iostream" #include "windows.h" #include "shlwapi.h" #include ...
- mongo基本语句
批量更新 db.test.updateMany({name:'test'},{$set:{value:1}}) 单更新 db.test.update({name:'test'},{$set:{valu ...
- SQLServer 使用smb存放数据文件
安装smb: 服务器管理器->角色->文件服务 1.配置smb共享时,更改NTFS权限,需要将SQLServer启动域帐户加入,读.写.完全控制等权限 2.实例启动用户需要使用域帐户 3. ...
- RobotFrameWork webservice soap接口测试 (二)
上一篇提到做soap接口测试自己简单的写了个py,然后就简单的实现了个客户端能对远程接口进行调用,对返回的数据进行解析,可后面想着也觉得不对劲,soap协议虽说不像http协议那么普及,但是现在很多公 ...
- LINQ to SQL Count/Sum/Min/Max/Avg Join
public class Linq { MXSICEDataContext Db = new MXSICEDataContext(); // LINQ to SQL // Count/Sum/Min/ ...
- InnerJoin分页导致的数据重复问题排查
2016年8月9号美好的七夕的早上,我精神抖擞地来到公司.一会之后,客服宅宅MM微信我,说一个VIP大店铺订单导出报表中一个订单有重复行.于是,我赶紧开始查探问题所在.经过一天的反复仔细追查(当然还包 ...
- 03-组合逻辑电路设计之译码器——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线——普利斯队长精心奉献 课程目标: 1. 再次熟悉Quartus II工程的建立以及完整的FPGA开发流程 2. 以译码器为例学会简单组合逻辑电路设计 实验平台:无 实验原理: 组合逻辑, ...