Remember the Word UVALive - 3942 DP_字典树
每个小单词的长度都是小于等于100的,这是个重要的突破口.
Code:
#include <cstdio> #include <algorithm> #include <cstring> #define setIO(s) freopen(s".in","r",stdin) #define maxn 300006 #define mod 20071027 using namespace std; char str[maxn],wd[maxn]; int tag[maxn],n,f[maxn],m,cas; struct TRIE{ #define SIGMA 30 int root,ch[maxn][SIGMA],cnt; void init() { root = cnt = 0; memset(ch,0,sizeof(ch)); memset(tag,0,sizeof(tag)); memset(f,0,sizeof(f)); } void ins(char s[]) { int len = strlen(s),p = root; for(int i = 0;i < len; ++i) { if(!ch[p][s[i]-'a']) ch[p][s[i]-'a'] = ++cnt; p = ch[p][s[i]-'a']; } tag[p] = 1; } void solve(int st){ int p = root; for(int i = st;i <= m; ++i) { p = ch[p][str[i]-'a']; if(!p) break; if(tag[p]) f[st] += f[i + 1],f[st] %= mod; if(tag[p] && i == m) f[st] += 1; } } }trie; int main(){ //setIO("input"); while(scanf("%s",str) != EOF) { scanf("%d",&n),trie.init(),m = strlen(str) - 1; for(int i = 1;i <= n; ++i) scanf("%s",wd),trie.ins(wd); for(int i = m;i >= 0; --i) trie.solve(i); printf("Case %d: %d\n",++cas,f[0]); } return 0; }