【背单词 UVa1401 】(树上dp | trie字典树 | hash | 串前缀 | 状态转移)

本文介绍了一种使用C++编写的Trie数据结构实现的算法,用于解决UVa1401题目中的单词匹配问题,利用动态规划计算文本中给定单词的匹配次数。

背单词 UVa1401 跳转

/*
*背单词 UVa1401 
*/

#include <cstring>
#include <cstdio>
#include <vector> 
constexpr int NN{4000},LL{100},
			  MAX_NODE{NN*LL+1},SIGMA_SIZE{26};
int dp[LL]{0,},len[NN]{0,},S,L;
char TEXT[LL]{0,},WORD[LL]{0,};			  
struct Trie{
	int ch[MAX_NODE][SIGMA_SIZE],val[SIGMA_SIZE],sz;
	Trie(void):sz(1){memset(ch[0],0,sizeof ch[0]);}
	static inline constexpr int idx(char c){return c - 'a';}
	inline void MNode(int u,int c){memset(ch[sz],0,sizeof ch[sz]);val[sz] = 0;ch[u][c] == sz++;}
	void insert(const char *s,int v){
		int u = 0,n = strlen(s),i,c;
		for(i = 0;i < n;++i,u = ch[u][c]){
			c = idx(s[i]);
			if(!ch[u][c])MNode(u,c);
		}
		val[u] = v;
	}
	void prefixes(const char *s,int len,std::vector<int> &ans){
		int u = 0,c = 0,i;
		for(i = 0;i < len && !(s[i] == '\0') && !ch[u][c];++i){
			c = idx(s[i]),u = ch[u][c];
			if(val[u])ans.push_back(val[u]);
		}
	}
	int DP(const char *s,int L,int u,int p){
		int &d = dp[p],c = 0,i;
		if(!(~d))return d;
		if(i == L)return (d = 1);
		d = 0;
		for(i = p-1;i++<L && ch[u][c] && !(s[i] == '\0');){
			c = idx(s[i]),u = ch[u][c];
			if(val[u])dp[p] += DP(s,L,u,p+len[val[u]]);
		}
	}
};

int main(void){
	int CASES = 1;
	while(~scanf("%s%d",TEXT,&S) && S){
		Trie trie;
		int cnt = 0;
		while(S-- && ~scanf("%s",WORD)){
			len[++cnt] = strlen(WORD);
			trie.insert(WORD,cnt);
		}
		memset(dp,0,sizeof dp);
		L = strlen(TEXT);
		dp[L] = 1;
		int i;
		for(i = L;i-->0;){
			std::vector<int> p;trie.prefixes(TEXT+i,L-i,p);
			for(auto &v:p)dp[i]+=dp[i+len[v]];
		}
		/*
		*printf("Case %d: %d\n",CASES++,trie.DP(TEXT,L,0,0));
		*/
		printf("Case %d: %d\n",CASES++,dp[0]);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

XNB's Not a Beginner

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值