• POJ2004 Mix and build Trie树? dp?


    学习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]='';
    		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
    ",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;
    }
    
  • 相关阅读:
    ABP框架插件开发
    ionic 向路由中的templateUrl(模板页)传值
    EFT4 生成实体类
    mvc 下的 signalR使用小结
    利用javascript实现页面截图
    linux定时任务php
    PHPCMSV9的CKEDITOR编辑器增加行距
    上传网站后建议执行:chown www:www -R /path/to/dir 对网站目录进行权限设置,/path/to/dir替换为你网站目录。
    centOS7下安装GUI图形界面
    虚拟机中的Linux安装VMware Tools的方法
  • 原文地址:https://www.cnblogs.com/chanme/p/3484716.html
Copyright © 2020-2023  润新知