首页 > 代码库 > uva1401 dp+Trie
uva1401 dp+Trie
这题说的是给了一个长的字符串长度最大300000,又给了4000个单词 单词的长度不超过100.计算这个字符串能组成多少种不同单词的组合,求出方案总数。dp[i]以第i个字符为开始的字符串能有多少种的组成方案,这样每次去比较肯定是会超时的,然后可以用Trie树去优化,这样最多枚举100位种比4000位来得快很多
#include <iostream>#include <cstdio>#include <string.h>#include <vector>using namespace std;const int maxn = 100*4000+10;const int signma_size =26;const int mod = 20071027;struct Trie{ int ch[maxn][signma_size]; int val[maxn]; int sz; Trie(){ sz=1; memset(ch[0],0,sizeof(ch[0]));} int idx(char c){ return c-‘a‘; } void clear(){ sz=1; memset(ch[0],0,sizeof(ch[0])); } void insert(char *s,int v){ int u=0,n=strlen(s); for(int i=0; i<n; ++i){ int c= idx(s[i]); if(ch[u][c]==0){ memset(ch[sz],0,sizeof(ch[sz])); val[sz]=0; ch[u][c]=sz++; } u=ch[u][c]; } val[u]=v; } void find(char *s,int n,vector<int> &va) { int u=0; for(int i=0; i<n; ++i){ int c=idx(s[i]); if(ch[u][c]==0) break; u=ch[u][c]; if(val[u]!=0) va.push_back(val[u]); } }}A;char text[300005],str[4005][105];int Len[4005],dp[300005];int main(){ int S,cas=0; while(scanf("%s%d",text,&S)==2){ A.clear(); int n=strlen(text); for(int i=1; i<=S; i++){ scanf("%s",str[i]); A.insert(str[i],i); Len[i]=strlen(str[i]); } dp[n]=1; vector<int> Val; for(int i=n-1; i>=0; i--){ A.find(text+i,n-i,Val); dp[i]=0; int L=Val.size(); for(int j=0; j<L; ++j){ int t=Val[j]; dp[i]=( dp[i] + dp[ i+Len[ t ] ])%mod; } Val.clear(); } printf("Case %d: %d\n",++cas,dp[0]); } return 0;}
uva1401 dp+Trie
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。