标签:
分析:d[i]=sum{ d(i+len(x) } [i,L]的种类数
可以正向枚举,也可以逆向枚举,Trie+dp的结合题,第一次见,其实dp的思维还是比较简单的
<pre class="cpp" name="code">#include <cstdio> #include <cstring> #include <string> #include <iostream> #include <algorithm> using namespace std; const int mod=20071027; struct TrieNode { bool vis; struct TrieNode *next[26]; }; typedef TrieNode Trie; Trie *root; char str[300006]; long long dp[300006]; Trie *CreateNode() { Trie *p=(Trie*)malloc(sizeof(Trie)); p->vis=false; for (int i=0;i<26;i++) p->next[i]=NULL; return p; } void Insert(string str) { Trie *p=root; int len=str.size(); for (int i=0;i<len;i++) { int id=str[i]-'a'; if (p->next[id] == NULL) { p->next[id]=CreateNode(); p=p->next[id]; } else p=p->next[id]; } p->vis=true; } void Search(int ii,int len) { Trie *p=root; dp[ii]=0; for (int i=ii;i<len;i++) { int id=str[i]-'a'; p=p->next[id]; if (p == NULL) break; if (p->vis == true) dp[ii]=(dp[ii] + dp[i+1]) % mod; } } int main() { int j=0; while (~scanf("%s",str)) { root=CreateNode(); int len=strlen(str); int n; scanf("%d",&n); string s; for (int i=1;i<=n;i++) { cin>>s; Insert(s); } dp[len]=1;//精髓 for (int i=len-1;i>=0;i--) { Search(i,len); } printf("Case %d: %d\n",++j,dp[0]); } }
标签:
原文地址:http://blog.csdn.net/qq_32036091/article/details/51344229