• P3041 [USACO12JAN]Video Game G


    P3041 [USACO12JAN]Video Game G

    完全不知道为什么数据范围这么小,而且我一遍写完就AC了。。。

    考虑如果我们知道了 (Bessie) 输入的字符串,那么答案就是:把所有模式串建 (ACAM) ,让文本串沿着 (Trie) 图跑,所有经过的节点打标记,统计每个模式串终止节点子树内的标记个数和。

    可是这个字符串是自己构造的。。。

    我们发现我们可以知道走到 (Trie) 图上面的每一个节点产生的贡献:即从它到根的路径上有几个模式串的终止节点,因为一旦走到这个点,那些终止节点的子树和都会加一。

    所以现在的问题是:你的面前有一张图,点数不超过 (300) ,有点权,求长度为 (k(kle 1000)) 的路径中经过点的点权和最大是多少

    (dp[i][j]) 表示在 (i) 这个节点还可以(或者已经走)走 (j) 步的方案数,直接 (dp) 或者记搜就能过了。

    复杂度 (O(sum |S|cdot k))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    typedef double db;
    #define x first
    #define y second
    #define sz(v) (int)v.size()
    #define pb(x) push_back(x)
    #define mkp(x,y) make_pair(x,y)
    inline int read(){
    	int x=0,f=1;char c=getchar();
    	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
    	while(isdigit(c))x=x*10+c-'0',c=getchar();
    	return f?x:-x;
    }
    int n,k,ch[305][3],tot,cnt[305],dp[305][1005],fail[305];
    vector<int>e[305];
    void insert(char*str){
    	int u=0,len=strlen(str);
    	for(int i=0;i<len;++i){
    		int c=str[i]-'A';
    		if(!ch[u][c])ch[u][c]=++tot;
    		u=ch[u][c];
    	}
    	++cnt[u];
    }
    void build_fail(){
    	queue<int>q;
    	for(int i=0;i<3;++i)if(ch[0][i])q.push(ch[0][i]);
    	while(!q.empty()){
    		int u=q.front();q.pop();
    		for(int i=0;i<3;++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];
    	}
    	for(int i=1;i<=tot;++i)e[fail[i]].pb(i);
    }
    void dfs1(int u){
    	for(int v:e[u])cnt[v]+=cnt[u],dfs1(v);
    }
    int dfs2(int u,int k){
    	if(~dp[u][k])return dp[u][k];
    	if(!k)return cnt[u];
    	int res=0;
    	for(int i=0;i<3;++i)res=max(res,dfs2(ch[u][i],k-1));
    	return dp[u][k]=res+cnt[u];
    }
    signed main(){
    	n=read(),k=read();
    	for(int i=1;i<=n;++i){
    		static char str[20];
    		scanf("%s",str),insert(str);
    	}
    	build_fail(),dfs1(0);
    	memset(dp,-1,sizeof(dp));
    	printf("%d
    ",dfs2(0,k));
    }
    
  • 相关阅读:
    [树形DP]Luogu P1131 [ZJOI2007]时态同步
    [状压DP]JZOJ 1303 骑士
    [DFS]JZOJ 1301 treecut
    [最小费用最大流]JZOJ 4802 探险计划
    [KMP][倍增求LCA]JZOJ 4669 弄提纲
    [DP]JZOJ 1758 过河
    列表生成式和生成器表达式
    协程函数
    生成器
    迭代器
  • 原文地址:https://www.cnblogs.com/zzctommy/p/13889367.html
Copyright © 2020-2023  润新知