zoukankan      html  css  js  c++  java
  • 【USACO12JAN】—视频游戏的连击Video Game Combos(AC自动机+dp)

    描述

    贝西在玩一款游戏,该游戏只有三个技能键 “A”“B”“C”可用,但这些键可用形成N种(1 <= N<= 20)特定的组合技。第i个组合技用一个长度为1到15的字符串S_i表示。

    当贝西输入的一个字符序列和一个组合技匹配的时候,他将获得1分。特殊的,他输入的一个字符序列有可能同时和若干个组合技匹配,比如N=3时,3种组合技分别为"ABA", “CB”, 和"ABACB",若贝西输入"ABACB",他将获得3分。

    若贝西输入恰好K (1 <= K <= 1,000)个字符,他最多能获得多少分?

    输入

    Line 1: Two space-separated integers: N and K.

    Lines 2…N+1: Line i+1 contains only the string S_i, representing combo i.

    输出

    Line 1: A single integer, the maximum number of points Bessie can obtain.

    样例输入

    3 7
    ABA
    CB
    ABACB

    样例输出

    4

    提示

    The optimal sequence of buttons in this case is ABACBCB, which gives 4 points–1 from ABA, 1 from ABACB, and 2 from CB.


    每次暴力枚举下一个字符填什么在acac自动机上dp就完了
    注意下传endend

    #include<bits/stdc++.h>
    using namespace std;
    #define gc getchar
    inline int read(){
    	char ch=gc();
    	int res=0,f=1;
    	while(!isdigit(ch))f^=ch=='-',ch=gc();
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
    	return f?res:-res;
    }
    #define pb push_back
    #define re register
    #define cs const
    #define ll long long
    #define pii pair<int,int>
    #define fi first
    #define se second
    inline void chemx(int &a,int b){
    	a<b?a=b:0;
    }
    inline void chemn(int &a,int b){
    	a>b?a=b:0;
    }
    const int N=305;
    namespace Ac{
    	int nxt[N][3],fail[N],end[N],tot;
    	inline void insert(char *s){
    		int p=0;
    		for(int i=1,len=strlen(s+1);i<=len;i++){
    			int c=s[i]-'A';
    			if(!nxt[p][c])nxt[p][c]=++tot;
    			p=nxt[p][c];
    		}
    		end[p]++;
    	}
    	queue<int> q;
    	inline void build(){
    		for(int i=0;i<3;i++){
    			int v=nxt[0][i];
    			if(v)q.push(v),fail[v]=0;
    		}
    		while(!q.empty()){
    			int p=q.front();q.pop();
    			for(int c=0;c<3;c++){
    				int v=nxt[p][c];
    				if(!v)nxt[p][c]=nxt[fail[p]][c];
    				else fail[v]=nxt[fail[p]][c],q.push(v);
    			}
    			end[p]+=end[fail[p]];
    		}
    	}
    	int f[1005][N];
    	inline int dp(int n){
    		memset(f,-1,sizeof(f));
    		f[0][0]=0;
    		for(int i=0;i<n;i++)
    		for(int j=0;j<=tot;j++){
    			if(f[i][j]==-1)continue;
    			for(int c=0;c<3;c++)
    			chemx(f[i+1][nxt[j][c]],f[i][j]+end[nxt[j][c]]);
    		}int res=0;
    		for(int i=0;i<=tot;i++)chemx(res,f[n][i]);
    		return res;
    	}
    }
    int n,m;
    char s[N];
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)
    	scanf("%s",s+1),Ac::insert(s);
    	Ac::build();
    	cout<<Ac::dp(m);
    }
    
  • 相关阅读:
    poj 3616 Milking Time
    poj 3176 Cow Bowling
    poj 2229 Sumsets
    poj 2385 Apple Catching
    poj 3280 Cheapest Palindrome
    hdu 1530 Maximum Clique
    hdu 1102 Constructing Roads
    codeforces 592B The Monster and the Squirrel
    CDOJ 1221 Ancient Go
    hdu 1151 Air Raid(二分图最小路径覆盖)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328781.html
Copyright © 2011-2022 走看看