zoukankan      html  css  js  c++  java
  • [USACO12JAN] Video Game Combo

    给定 (N) 个模式串。一个母串的分数定义为能与模式串匹配的次数,可以与同一个模式串多次匹配。问一个长度为 (K) 的母串最多能获得多少分。(Nleq 20,K leq 1000)

    Solution

    考虑在 AC 自动机上 DP,令 (f[i][j]) 表示走了 (i) 个字符,到达结点 (j),则

    [f[i][j]+val[ch[j][k]] o f[i+1][ch[j][k]] ]

    其中 (val[p]) 表示结点 (p) 到 fail 树根的链上有多少个末端

    #include <bits/stdc++.h>
    using namespace std;
    int val[1005],ch[1005][3],fi[1005],dp[1005][1005],ind,n,m;
    char str[1005];
    void insert(char *s){
    	int len=strlen(s),p=0;
    	for(int i=0;i<len;i++){
    		int v=s[i]-'A';
    		if(!ch[p][v]) ch[p][v]=++ind;
    		p=ch[p][v];
    	}
    	val[p]++;
    }
    void build(){
    	queue <int> q;
    	for(int i=0;i<3;i++)
    		if(ch[0][i])
    			q.push(ch[0][i]);
    	while(!q.empty()){
    		int p=q.front(); q.pop();
    		for(int i=0;i<3;i++)
    			if(ch[p][i]) fi[ch[p][i]]=ch[fi[p]][i], q.push(ch[p][i]);
    			else ch[p][i]=ch[fi[p]][i];
    		val[p]+=val[fi[p]];
    	}
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++) scanf("%s",&str), insert(str);
    	build();
    	memset(dp,0x80,sizeof dp);
    	for(int i=0;i<=m;i++) dp[i][0]=0;
    	for(int i=1;i<=m;i++){
    		for(int j=0;j<=ind;j++){
    			for(int k=0;k<3;k++){
    				dp[i][ch[j][k]]=max(dp[i][ch[j][k]],dp[i-1][j]+val[ch[j][k]]);
    			}
    		}
    	}
    	int ans=0;
    	for(int i=0;i<=ind;i++)
    		ans=max(ans,dp[m][i]);
    	printf("%d
    ",ans);
    }
    
  • 相关阅读:
    用户描述
    课堂练习
    一阶段11.21
    一阶段11.20
    一阶段 11.19
    自己动手写spring(五) bean的生命周期管理
    自己动手写spring(四) 整合xml与注解方式
    自己动手写spring(三) 支持注解方式
    自己动手写spring(二) 创建一个bean工厂
    自己动手写spring(一) 使用digester
  • 原文地址:https://www.cnblogs.com/mollnn/p/12450070.html
Copyright © 2011-2022 走看看