SPOJ 7758 MGLAR10 - Growing Strings
来源:互联网 发布:centos编译c 编辑:程序博客网 时间:2024/06/09 16:23
题目链接:SPOJ7758
MGLAR10 - Growing Strings
EnglishVietnamese
Input
Each test case is given using several lines. The first line contains an integer N representing the number of strings in the set (1 ≤ N ≤ 10^4). Each of the following N lines contains a different non-empty string of at most 1000 lowercase letters of the English alphabet. Within each test case, the sum of the lengths of all strings is at most 10^6.
The last test case is followed by a line containing one zero.
Output
For each test case output a single line with a single integer representing the size of the largest sequence of photos that can be produced.
Sample
input
6plantantcantdecantdecaan2supercalifragilisticexpialidociousrag0
output
42
题目分析:SPOJ的账号申请半天,结果一直都是申请失败,不知道为啥,,,而且网上题解少的可怜,,白瞎这么好的题了。。。。
这题主要考察AC自动机和DP,先要把每个字符串加入字典树,作为标记末尾节点的num为1。然后构造fail指针。不过仔细考察fail指针的意义就会发现我们可以在构造fail指针的时候顺便就能把答案求出来。每个fail指针指向这个字符串的最长后缀的位置。我们在每个字典树的每个节点上加一个整型sum作为以从root到这个节点的字符串为最右面的字符串时左面最多能有多少字符串(这里如果这个字符串是完整的话就把自己也加上,否则的话不用)。
这样就比较明了了。只需取其的父节点p的sum值和p->next[i]->fail节点的sum值的最大项加上自己的num即可。状态转移方程p->next[i]->sum=max(p->sum,p->next[i]->fail->sum)+p->next[i]->num;每求出一个sum都和ans取最大值。构造完fail指针这题也差不多了。
//// main.cpp// SPOJ7758//// Created by teddywang on 16/4/11.// Copyright © 2016年 teddywang. All rights reserved.//#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,ans,num,ptr,head,tail;typedef struct node{ int flag; int num,sum; node *next[26]; node *fail;}trienode;trienode *root;trienode *qu[1000006];trienode *creat_node(){ trienode *r=new node; r->num=r->flag=r->sum=0; for(int i=0;i<26;i++) r->next[i]=NULL; r->fail=NULL; return r;}void init(){ root=creat_node(); ans=num=ptr=0; head=tail=0;}void insert_node(char *s){ trienode *r=root,*t; int len=strlen(s); for(int i=0;i<len;i++) { int buf=s[i]-'a'; if(r->next[buf]==NULL) { t=creat_node(); r->next[buf]=t; r=t; } else r=r->next[buf]; } r->flag=1;r->num=1;}void build_ac(){ qu[head++]=root; while(tail<head) { trienode *p=qu[tail++]; for(int i=0;i<26;i++) { if(p->next[i]!=NULL) { if(p==root) p->next[i]->fail=root; else { trienode *temp=p->fail; while(temp!=NULL) { if(temp->next[i]!=NULL) { p->next[i]->fail=temp->next[i]; break; //p->next[i]->num+=temp->next[i]->num; } else temp=temp->fail; } if(temp==NULL) p->next[i]->fail=root; } p->next[i]->sum=max(p->sum,p->next[i]->fail->sum)+p->next[i]->num; ans=max(ans,p->next[i]->sum); qu[head++]=p->next[i]; } } }}void del(trienode *p){ for(int i=0;i<26;i++) { if(p->next[i]!=NULL) { del(p->next[i]); } } free(p);}int main(){ while(cin>>n&&n) { init(); for(int i=0;i<n;i++) { char s[2005]; scanf("%s",s); insert_node(s); } ans=0; build_ac(); cout<<ans<<endl; del(root); }}
注意要释放内存。
- SPOJ 7758 MGLAR10 - Growing Strings
- SPOJ 7758 Growing Strings AC自动机DP
- SPOJ 7758. Growing Strings (ac自动机+dp)
- SPOJ7758--- Growing Strings
- spoj7758 Growing Strings ac机+dp
- UVALive 4811 Growing Strings【AC自动机+简单dp】
- Growing elder.
- Growing Mushrooms
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- SPOJ
- Android下拉刷新SwipeRefreshLayout控件的简单使用
- windows7 集成nginx 1.8.1(稳定版本)
- 广搜的简单应用1015
- 无线破解攻击工具Aircrack-ng使用详解
- Java的Socket编程
- SPOJ 7758 MGLAR10 - Growing Strings
- Docker生态系统一览
- 解惑 -- static
- iis 安装织梦DedeCMS 教程
- djiango学习笔记(一)
- vimperator 常用操作命令一览表(3分钟回顾)
- 链表题目总结
- centos7上mysql的使用
- hdu3555 经典数位dp