首页 > 代码库 > UVA 1401Remember the WordDp
UVA 1401Remember the WordDp
此题开始 用记忆化搜索搞,我果然白痴,字符串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;}
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。