UVALive 3942 Remember the Word
题意:给出一个由S个不同单词组成的字典和一个长字符串。把这个字符串分解成若干个单词的连接(单词可以重复
使用),有多少种方法?
Sample Input
abcd
4
a
b
cd
ab
Sample Output
Case 1: 2
思路:利用字典树上的dp,dp[i]表示从i到末尾有多少种方案,大白书字典树的例题,虽然是例题还是看了一会儿orz,
我太弱了,注意ch数组要开成最大节点数*26的大小,表示每个节点连的字母是什么,初始节点为0,val也要开
成最大节点数的大小,表示该节点是否为单词的最后一个字母。
然后就是dp的过程了,从末尾往前,每次循环从i到结尾,如果碰到某个单词的结尾(也就是val[j]==1)就代表
该单词可以作为某些组合的一部分,dp[i]+=dp[j+1],关键部分就是这里了吧。
代码:
#include<iostream>
#include<string.h>
using namespace std;
const int maxn=4001*101;
const int maxm=3e5+5;
const int mod=20071027;
struct Trie{
int ch[maxn][26];
int val[maxn];
int sz;
Trie(){
sz=1;
memset(ch[0],0,sizeof(ch[0]));
}
int idx(char c){
return c-'a';
}
void insert(char *s,int v){
int u=0,l=strlen(s);
for(int i=0;i<l;i++){
int x=idx(s[i]);
if(ch[u][x]==0){
memset(ch[sz],0,sizeof(ch[sz]));
val[sz]=0;
ch[u][x]=sz++;
}
u=ch[u][x];
}
val[u]=v;
}
}e;
char s[maxm];
char a[110];
long long dp[maxm];
int main(){
int t=0;
while(~scanf("%s",s)){
int n;
scanf("%d",&n);
memset(e.ch[0],0,sizeof(e.ch[0]));
e.sz=1;
for(int i=0;i<n;i++){
scanf("%s",a);
e.insert(a,1);
}
int l=strlen(s);
memset(dp,0,sizeof(dp));
dp[l]=1;
int u;
for(int i=l-1;i>=0;i--){
u=0;
for(int j=i;j<l;j++){
int x=e.idx(s[j]);
if(e.ch[u][x]==0)break;
u=e.ch[u][x];
if(e.val[u])dp[i]+=dp[j+1];
}
dp[i]%=mod;
}
//printf("%d\n",e.sz);
//for(int i=0;i<=l;i++)printf("%lld ",dp[i]);
printf("Case %d: %lld\n",++t,dp[0]);
}
return 0;
}
UVALive 3942 Remember the Word的更多相关文章
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- 【暑假】[实用数据结构]UVAlive 3942 Remember the Word
UVAlive 3942 Remember the Word 题目: Remember the Word Time Limit: 3000MS Memory Limit: Unknown ...
- UVALive 3942 Remember the Word 字典树+dp
/** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...
- UVALive 3942 Remember The Word (Tire)
状态是DAG,因此方案用dp统计,dp[i] = sum(dp[i+len(x)]),x是以i开头的前缀且是单词,关键在于快速判断一个前缀是不是单词,可用Trie. 每一次转移的复杂度是O(maxle ...
- UVALive - 3942 Remember the Word (Trie + DP)
题意: 给定一篇长度为L的小写字母文章, 然后给定n个字母, 问有多少种方法用这些字母组成文章. 思路: 用dp[i]来表达[i , L]的方法数, 那么dp[i] 就可以从dp[len(x) + i ...
- UVALive 3942 Remember the Word(字典树+DP)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- (Trie) uvalive 3942 Remember the word
题意:告诉你一个母串和子串,能用多少种不同的方案组合出母串. 思路:字典树(显然)+DP DP: dp[i]+=dp[j+1] i<=j<=m-1,且i到j的字符串能在字典树中找到.也就 ...
- LA 3942 Remember the Word(前缀树&树上DP)
3942 - Remember the Word Neal is very curious about combinatorial problems, and now here comes a pro ...
随机推荐
- (引用)!Unicode,GBK以及UTF8的联系和区别
在实现单片机显示汉字的操作时,了解到有关汉字编码的相关概念. Unicode是一种字符集,该字符集可以涵盖世界上所有的语言.最常见的字符集是ASC II-0~127(0x00~0x7f).Unicod ...
- linux删除文件后,空间未释放的一种情况,使用lsof查看
linux某个目录空间快满了,删除了若干的文件后,使用df -h显示还是快满的,但是df -h *显示的总的文件大小又没那么大. 某个进程正在使用删除的文件,导致删除后,空间仍然不能释放. 查看rm掉 ...
- php如何和linux进行通讯
FastCGI原理 FastCGI是一个运用于Http Server和动态脚本语言间通信的接口,多数流行的Http Server都支持FastCGI,包括Apache.Nginx和lighttpd等. ...
- Python 之 type方法创建类
type()方法作为元类,用来创建类: type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值)) 以下代码可以用type()方法来创建: class Myclass(ob ...
- 面试题_默认传参list
# ###2.值是多少 def extendList(val, list=[]): list.append(val) return list 如果默认形参是列表,会提前在内存中开辟一个空间存储列表 如 ...
- oracle_hc.sql
select event,count(1) from gv$session group by event order by 2;exec dbms_workload_repository.create ...
- unity检测鼠标是点击在UI上还是物体上
void Update() { if (Input.GetMouseButtonDown(0)||(Input.touchCount >0 && Input.GetTouch(0 ...
- C 语言实现基于 Linux 的端口扫描程序
Socket 常用函数: ⑴int socket(int protofamily, int type, int protocol); protofamily:即协议域,又称为协议族(family).常 ...
- Vue 学习(1)
<!DOCTYPE html> <html lang="en" dir="ltr"> <head> <meta cha ...
- [Unity优化]批处理03:静态批处理
原理: 运行时,把需要进行静态批处理的网格合并到一个新的网格中.虽然只进行一次合并操作,但是会占用更多的内存来存储合并后的网格,并且被静态批处理的物体无法移动旋转缩放 要使用静态批处理,需要把Stat ...