标签:style blog color os io for ar div
此题开始 用记忆化搜索搞,我果然白痴,字符串30w 的长度 ,爆栈是肯定的。
dp转移的方程: str[i->j] 如果出现 dp[i] += dp[j+1]
然后用字典树查询 str[i->j]是否出现过。
#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; }
UVA 1401Remember the WordDp,布布扣,bubuko.com
标签:style blog color os io for ar div
原文地址:http://www.cnblogs.com/yigexigua/p/3907120.html