uva 1401 - Remember the Word(字典树)
来源:互联网 发布:apache ip访问 编辑:程序博客网 时间:2024/05/21 05:21
题意:给一个长串(长度1~300000),s(1~4000)个单词,问长串可以完全分解成单词的方案种数?
解析:先保存单词前缀,然后将长串严格从左往右枚举以i位置为首的前缀数,注意剪枝(不重复),一次搜索后的结尾位置的后一个位置作为下次搜索的起始位置(进入优先队列,保证严格从左往右搜索)dp【i】表示以i位置为结尾的方案数,则dp【i】+=dp【w-1】;w为本次搜索的初始位置,一次循环就可以得到答案,
#include<iostream>#include<cstdio>#include<string.h>#include<functional>#include<queue>#include<vector>#include<algorithm>using namespace std;#define N 300005#define mod 20071027typedef long long LL;char s[N];int n,len,dp[N],vis[N],res;priority_queue<int, vector<int>, greater<int> > sea;struct node{ int prefix; bool isword; node *next[27]; node() { prefix=0; isword=false; memset(next,NULL,sizeof(next)); }} *root;void insert(char *a){ node *p=root; for(int i=0; a[i]; i++) { int x=a[i]-'a'; if(p->next[x]==NULL) p->next[x]=new node; p=p->next[x]; } p->isword=true; p->prefix++;}void search(int w){ node *p=root; // if(w==len) { res++; if(res>mod) res=res-mod; return; } for(int i=w; i<len; i++) { int x=s[i]-'a'; if(p->next[x]==NULL) break; p=p->next[x]; if(p->isword) { dp[i]+=dp[w-1]; if(dp[i] >= 20071027) dp[i] %= 20071027; if(!vis[i+1]) { vis[i+1]=1; sea.push(i+1); } } } while(!sea.empty()) { int t=sea.top();//优先队列保证严格从左往右搜索 sea.pop(); search(t); }}int main(){ int i,j,t=1; char a[105]; while(~scanf("%s",s+1)) { scanf("%d",&n); s[0]='!'; res=0; len=strlen(s); root=new node; for(i=0; i<n; i++) { scanf("%s",&a); insert(a); } memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); dp[0]=1; vis[1]=1; search(1); printf("Case %d: %d\n",t++,dp[len-1]%mod); free(root); } return 0;}
- UVa:1401 Remember the Word(字典树)
- UVA 1401 Remember the Word(字典树)
- uva 1401 - Remember the Word(字典树)
- UVA 1401 Remember the Word(字典树)
- UVA 1401 Remember the Word(DP+字典树Trie)
- uva 1401 - Remember the Word(字典树+dp)
- UVA 1401 & LA 3942 Remember the Word 字典树+DP
- Uva 1401 Remember the Word 字典树+DP
- UVa 1401 Remember the Word (字典树, 动归)
- UVA 1401 Remember the Word(DP+字典树Trie)
- 【UVA】Remember the Word(Trip树)
- Uva-1401-Remember the Word
- UVA 1401 Remember the Word
- uva 1401 - Remember the Word
- UVa 1401 Remember the Word
- UVA 1401 Remember the Word
- UVA 1401 Remember the Word
- UVA 1401 Remember the Word
- 交换机和路由器的区别
- Mathematical Aspect of Linux Shell Programming – Part IV
- SqlServer里DateTime转字符串
- dom 打印出xml中元素节点
- c语言 常用的库函数
- uva 1401 - Remember the Word(字典树)
- 阿里巴巴2010-2013校园招聘笔试题
- 关于指针
- leetcode_question_128 Longest Consecutive Sequence
- android 将文件存到SD卡上
- Linux netstat命令详解
- NHK SHV 的 22.2 声道音频系统
- Create Multiple IP Addresses to One Single Network Interface
- 火狐设置每次刷新重新请求