zoukankan      html  css  js  c++  java
  • USACO 2.31 The Longest Prefix

    描述

    在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。生物学家对于把长的序列分解成较短的序列(即元素)很感兴趣。

    如果一个集合 P 中的元素可以通过串联(元素可以重复使用,相当于 Pascal 中的 “+” 运算符)组成一个序列 S ,那么我们认为序列 S 可以分解为 P 中的元素。元素不一定要全部出现(如BBC就没有出现)。举个例子,序列 ABABACABAAB 可以分解为下面集合中的元素:

    {A, AB, BA, CA, BBC}

    序列 S 的前面 K 个字符称作 S 中长度为 K 的前缀。设计一个程序,输入一个元素集合以及一个大写字母序列 S ,设S'是序列S的最长前缀,使其可以分解为给出的集合P中的元素,求S'的长度K。

    格式

    PROGRAM NAME: prefix

    INPUT FORMAT

    输入数据的开头包括 1..200 个元素(长度为 1..10 )组成的集合,用连续的以空格分开的字符串表示。字母全部是大写,数据可能不止一行。元素集合结束的标志是一个只包含一个 “.” 的行。集合中的元素没有重复。接着是大写字母序列 S ,长度为 1..200,000 ,用一行或者多行的字符串来表示,每行不超过 76 个字符。换行符并不是序列 S 的一部分。

    OUTPUT FORMAT

    只有一行,输出一个整数,表示 S 符合条件的前缀的最大长度。

    SAMPLE INPUT (file prefix.in)

    A AB BA CA BBC
    .
    ABABACABAABC
    

    SAMPLE OUTPUT (file prefix.out)

    11
    
     
    分析:一开始觉得,trie+dfs+kmp好经典的呀,可惜对这题目而已,效率太低了,果断TLE;
    之后,用DP做的,这个思想就比较简单了,dp[i]表示当前位置是否可达,
    状态转移方程:dp[i+len[j]]=dp[i];(0<=j<m) j表示当前的字典里的元素
    #include<iostream>
    #include<algorithm>
    #include<string.h>
    #include<fstream>
    using namespace std;
    struct dic
    {
    	char str[11];
    	int len;
    }d[210];
    char s[200100];
    bool dp[200200]={0};
    bool cmp(dic a,dic b)
    {
    	return a.len>b.len;
    }
    int main()
    {
    	freopen("prefix.in","r",stdin);
    	freopen("prefix.out","w",stdout);
    	char str[11],str2[80];
    	int m=0;
    	while(scanf("%s",str)==1)
    	{
    		if(strcmp(str,".")==0)
    			break;
    		strcpy(d[m].str,str);
    		d[m++].len=strlen(str);
    	}
    //	sort(d,d+m);
    	s[0]='\0';
    	while(cin>>str2)
    		strcat(s,str2);
    	int len1=strlen(s);
    	dp[0]=1;
    	int ans=0;
    	for(int i=0;i<len1;i++)
    	{
    		if(!dp[i]) continue;
    		for(int j=0;j<m;j++)
    		{
    			int flag=0;
    			for(int k=0;k<d[j].len;k++)
    			{
    				if(d[j].str[k]!=s[i+k])
    				{
    					flag=1;break;
    				}
    			}
    			if(!flag) {
    				dp[i+d[j].len]=1;
    				if(i+d[j].len>ans)
    					ans=i+d[j].len;
    			}
    		}
    	}
    	cout<<ans<<endl;
    }
    

     下面这个是一开始超时的代码

    #include<iostream>
    #include<algorithm>
    #include<fstream>
    #include<string.h>
    using namespace std;
    typedef struct node  
    {  
        node *next[26];  
        int v;  
    }*tree,t;  
    tree root;  
    int ans;
    char str[200010];
    void insert(char *s)  
    {  
        tree p=root,newnode;  
        for(;*s!='\0';s++)  
        {  
            int d=*s-'A';  
            if(p->next[d]!=NULL)  
                p=p->next[d];  
            else  
            {  
                newnode=(tree)malloc(sizeof(t));  
                for(int i=0;i<26;i++)  
                    newnode->next[i]=NULL;  
                newnode->v=-1;   
                p->next[d]=newnode;  
                p=newnode;  
            }  
        }  
        p->v=1;  
    }  
    void dfs(char *s,int cnt)
    {
    	tree p=root;
    	char *s1=s;
    	if(cnt>ans)
    		ans=cnt;
    //	cout<<s<<endl;
    //	cout<<cnt<<endl;
    	for(int i=1;*s1!='\0';s1++,i++)
    	{
    		int d=*s1-'A';
    		p=p->next[d];
    		if(p==NULL)
    			return;	
    	//	cout<<d<<' '<<p->v<<endl;
    		if(p->v==1)
    		{
    		//	cout<<"long "<<i<<endl;
    			dfs(s+i,cnt+i);
    		}
    	}
    }
    int main()
    {
    	char str1[20],str2[76];
        root=(tree)malloc(sizeof(t));  
        for(int i=0;i<26;i++)  
            root->next[i]=NULL;  
        root->v=-1;  
    	freopen("prefix.in","r",stdin);
    	freopen("prefix.out","w",stdout);
    	while(scanf("%s",str1)==1)
    	{
    		if(strcmp(str1,".")==0)
    			break;
    		insert(str1);
    	}
    	ans=0;
    	str[0]='\0';
    	while(cin>>str2)
    		strcat(str,str2);
    //	cin>>str;
    	dfs(str,0);
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    yuv文件并行解析播放
    视频解析
    有意思的并查集讲解 收藏
    C++输入输出重载
    python 同步IO
    多线程与多进程的理解
    centos7 配置redis
    linux中的raid
    form表单系列中文件上传及预览
    centos7 安装swftools Apache_OpenOffice
  • 原文地址:https://www.cnblogs.com/nanke/p/2250922.html
Copyright © 2011-2022 走看看