题解 UVA1401 【Remember the Word】
题目链接:Link
Solution
第一次写Trie,写篇题解纪念一下......
令d(i)表示从字符i开始的字符串(即后缀 S[i...L-1])的分解方案数,则d(i)=sum{d(i+len(x)) | 单词x是 S[i...L-1]的前缀}。
显然,关键点就在判断前缀上。可以把所有的单词组织成Trie,然后试着在Trie中查找S[i...L-1],每找到一个单词节点,就状态转移一次....
#include<cstdio> #include<cstring> const int mod=20071027; const int maxL=300000; int L,S,d[maxL+5],kase; char str[maxL+5],tmp[105]; const int maxnode=4000*105;//注意开大一点 const int sigma_size=26; struct Trie { int ch[maxnode][sigma_size]; bool val[maxnode]; int sz; Trie() { sz=1; } inline void clear() { sz=1; memset(ch,0,sizeof(ch)); memset(val,0,sizeof(val));//一次性赋值 } inline void insert(char *s) { int u=0,n=strlen(s); for(int i=0;i<n;i++) { int c=s[i]-'a'; if(!ch[u][c]) ch[u][c]=sz++;//申请新节点 u=ch[u][c]; } val[u]=1; } }trie; int main() { #ifdef local freopen("pro.in","r",stdin); #endif while(scanf("%s",str)==1) { L=strlen(str); scanf("%d",&S); memset(d,0,sizeof(d)); trie.clear(); for(int i=0;i<S;i++) { scanf("%s",tmp); trie.insert(tmp); } d[L]=1;//边界 for(int i=L-1;i>=0;i--) for(int j=0,u=0;i+j<L&&trie.ch[u][str[i+j]-'a'];j++) { u=trie.ch[u][str[i+j]-'a']; if(trie.val[u]) d[i]=(d[i]+d[i+j+1])%mod; //状态转移 } printf("Case %d: %d\n",++kase,d[0]); } return 0; }
本作品由happyZYM采用知识共享 署名-非商业性使用-相同方式共享 4.0 (CC BY-NC-SA 4.0) 国际许可协议(镜像(简单版)镜像(完整版))进行许可。
转载请注明出处:https://www.cnblogs.com/happyZYM/p/11380110.html (近乎)全文转载而非引用的请在文首添加出处链接。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥