• [USACO13MAR] 项链Necklace


    项链Necklace

    贝西收集了N颗石头,每颗石头上都有一个字母,贝西想把这些石头做成项链。

    贝西的身边有另一只奶牛,这只奶牛的名字是一个长度为M的字符串,贝西不希望这只牛的名字出现在她的项链上(项链的子串),她想知道,最少删掉几颗石头就可以避免这种情况发生。

    The_Virtuoso的题解

    首先如果用AC自动机做这道题显然要把B串建在AC自动机上(AC自动机上就一个串好像有点浪费qwq)。要想B串不出现在A串中,只要把A串在AC自动机上跑,使它一直不遍历到B串的终止节点就能保证B串不是A串的子串。想要最优解自然要dp,那么就可以定义f[i][j]表示A串的第i个字符匹配到了AC自动机上第j个节点保留的最长长度。对于A串上的每一个字符可以删除或者在AC自动机上往下走,最后用A串总长len减掉max{f[len][i]}就是最小删除数了。

    时间复杂度(O(N M))

    co int N=1e4+1,M=1e3+1;
    char s[N],t[M];
    namespace AC
    {
    	int tot;
    	int ch[M][26],val[M];
    	int fail[M];
    	
    	void ins(char s[],int n)
    	{
    		int u=0;
    		for(int i=0;i<n;++i)
    		{
    			int k=s[i]-'a';
    			if(!ch[u][k])
    				ch[u][k]=++tot;
    			u=ch[u][k];
    		}
    		val[u]=1;
    	}
    	
    	void getfail()
    	{
    		std::queue<int>Q;
    		for(int i=0;i<26;++i)
    			if(ch[0][i])
    				Q.push(ch[0][i]);
    		while(Q.size())
    		{
    			int u=Q.front();Q.pop();
    			for(int i=0;i<26;++i)
    			{
    				if(ch[u][i])
    				{
    					fail[ch[u][i]]=ch[fail[u]][i];
    					Q.push(ch[u][i]);
    				}
    				else
    					ch[u][i]=ch[fail[u]][i];
    			}
    		}
    	}
    	
    	int f[N][M];
    	
    	void solve(char s[],int n)
    	{
    		for(int i=0;i<n;++i)
    		{
    			int k=s[i]-'a';
    			for(int j=0;j<=tot;++j)
    			{
    				if(!val[ch[j][k]])
    					f[i+1][ch[j][k]]=std::max(f[i+1][ch[j][k]],f[i][j]+1);
    				if(!val[j])
    					f[i+1][j]=std::max(f[i+1][j],f[i][j]);
    			}
    		}
    		int ans=0;
    		for(int i=0;i<=tot;++i)
    			ans=std::max(ans,f[n][i]);
    		printf("%d
    ",n-ans);
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	scanf("%s",s);
    	scanf("%s",t);
    	AC::ins(t,strlen(t));
    	AC::getfail();
    	AC::solve(s,strlen(s));
    	return 0;
    }
    
  • 相关阅读:
    Java 读取某个目录下所有文件、文件夹
    poi根据excel模板导出Excel
    UML关系(泛化,实现,依赖,关联(聚合,组合))
    使用Git下载Hadoop的到本地Eclipse开发环境
    maven command to create your application
    Roo中的@Version
    oracle 给用户赋表空间
    hiberante 二级缓存设置
    procedure
    Oracle综合数据库管理命令集
  • 原文地址:https://www.cnblogs.com/autoint/p/10322512.html
Copyright © 2020-2023  润新知