I started to use the memory-based search. I am an idiot. the string length is 30 W, and stack explosion is affirmative.
DP transfer equation: Str [I-> J] If DP [I] + = DP [J + 1] appears
Then, use the dictionary tree to check whether STR [I-> J] has appeared.
#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <climits>#include <string>#include <iostream>#include <map>#include <cstdlib>#include <list>#include <set>#include <queue>#include <stack>using namespace std;char str[333333];struct Node{ int gaoguo ; struct Node* next[30];}node[2111111];const int mod= 20071027;int len;Node* newnode(){ memset(&node[len],0,sizeof(node[len])); return &node[len++];}Node *rt;void Insert(string s,Node*root){ int len2=s.size(); for(int i= 0;i< len2;i++){ int cc=s[i]-‘a‘; if(!root->next[cc]){ root->next[cc]=newnode(); } root=root->next[cc]; } root->gaoguo=1;}int ask(string s,Node *root){ int len2=s.size(); for(int i=0;i<len2;i++){ int cc=s[i]-‘a‘; if(root->next[cc]) root=root->next[cc]; else return -1; } return root->gaoguo;}int len1;int dp[333333];char str1[333333];int main(){ int n; int Icase= 0; while(scanf("%s",str)!=EOF){ memset(dp,0,sizeof(dp)); len1=strlen(str); scanf("%d",&n); len=0; rt = newnode(); for(int i=0;i<n;i++){ scanf("%s",str1); Insert(str1,rt); } printf("Case %d: ",++Icase); dp[len1]=1; for(int i=len1-1;i>=0;i--){ string s=""; for(int j=i;j<len1;j++){ s+=str[j]; // cout<<s<<" "<<ask(s,rt)<<endl; int cc=ask(s,rt);if(cc==-1) break; if(cc==1) dp[i]+=dp[j+1],dp[i]%=mod; } } cout<<dp[0]%mod<<endl; } return 0;}