学习Trie树中,所以上网搜一下Trie树的题,找到这个,人家写着是简单dp,那我就想着能学习到什么Trie树上的dp,但最后发现根本好像跟Trie树没有什么联系嘛...
题意就是给你很多个字符串(长度<20),然后如果两个字符串在排序完后,左边的一个+一个字符能变成右边的,这两个字符串连上一条边,然后求最长的边.我想了半天怎么跟Trie不搭边... 一个自然的想法是这样的,记d[i]为序号为i的字符串作为结束字符串的最长长度,我先把所有字符串根据长度由小到大排序,然后对每个字符串k,我每次把起中一个字符去掉,看这个新字符串j存不存在,如果存在d[k]=max(d[k],d[j]+1).然后记下最大的那个,递归打印一下好.如果非要用Trie那就是实现一个基本的插入查找的功能,这个哈希可能比它快多了,实在不行map也是可以的.不过Trie应该快过map.既然学习这个我就当作练下手吧...最近这两天都是RE..姿势不对呀
#include<iostream> #include<cstring> #include<string> #include<algorithm> #include<cstdio> #define maxn 10000 using namespace std; struct StrNode { char sd[25]; char s[25]; int id; bool operator < (const StrNode &b) const { return strlen(this->sd)<strlen(b.sd); } }str[maxn+50]; int d[maxn+50]; // 记下最大的距离 int prevv[maxn+50]; // 记下最大的上一个的那个 struct TrieNode { TrieNode *next[26]; int id; }T[30*maxn],*Trie; int trietop; void insert(char *s,int idx) { int len=strlen(s);TrieNode *p=Trie; for(int i=0;i<len;++i){ if(p->next[s[i]-'a']!=NULL){ p=p->next[s[i]-'a']; } else{ memset(T[trietop].next,0,sizeof(T[trietop].next));T[trietop].id=-1; p->next[s[i]-'a']=&T[trietop++]; p=p->next[s[i]-'a']; } } p->id=idx; } int find(char *s) { int len=strlen(s);TrieNode *p=Trie; for(int i=0;i<len;++i){ if(p->next[s[i]-'a']!=NULL){ p=p->next[s[i]-'a']; } else{ return -1; } } return p->id; } int query(char *s) { char tmp[25];int len=strlen(s);int cnt=0; int ret=-1,maxd=-1; for(int i=0;i<len;++i){ cnt=0; for(int j=0;j<len;++j){ if(i!=j) tmp[cnt++]=s[j]; } tmp[cnt]='\0'; int tret=find(tmp); if(tret!=-1&&d[tret]>maxd){ ret=str[tret].id; maxd=d[tret]; } } return ret; } void print(int x) { if(prevv[x]!=-1){ print(prevv[x]); } printf("%s\n",str[x].s); } int main() { trietop=0;memset(T[trietop].next,0,sizeof(T[trietop].next));T[trietop].id=-1;Trie=&T[trietop++]; int n=0;char ins[25];memset(prevv,-1,sizeof(prevv)); while(scanf("%s",ins)!=EOF) { strcpy(str[n].sd,ins); strcpy(str[n].s,ins); sort(str[n].sd,str[n].sd+strlen(str[n].sd)); ++n; } sort(str,str+n);for(int i=0;i<n;++i) str[i].id=i; insert(str[0].sd,0);d[0]=0; int maxid=0,maxdist=0; for(int i=1;i<n;++i){ int px=query(str[i].sd); if(px!=-1){ d[i]=d[px]+1;prevv[i]=px; if(d[i]>maxdist){ maxid=i; maxdist=d[i]; } } else { d[i]=0; } insert(str[i].sd,i); } print(maxid); return 0; }