题意:

给定一篇长度为L的小写字母文章, 然后给定n个字母, 问有多少种方法用这些字母组成文章。

思路:

用dp[i]来表达[i , L]的方法数, 那么dp[i] 就可以从dp[len(x) + i]转移过来, 注意dp[L+1]要初始化为1.

递推写法

#include <bits/stdc++.h>
using namespace std;
const int maxN = 3e5 + ;
const int mod = ;
char in[maxN];
int n;
struct Trie {
int ch[maxN][];
int val[maxN];
int sz;
void Init(){sz = ; memset(ch[], , sizeof(ch[])); memset(val, , sizeof(val));}
int idx(char c) {return c - 'a';}
void Insert(char *s){
int u = , n = strlen(s);
for(int i = ; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = n;
} }tree;
long long dp[maxN];
int main(){
// freopen("1.txt","r", stdin);
int kase = ;
while(~scanf("%s", in)){
tree.Init();
memset(dp , , sizeof(dp));
scanf("%d", &n);
char word[];
for(int i = ; i < n; i++){
scanf("%s", word);
tree.Insert(word);
}
int len = strlen(in);
dp[len] = ;
for(int pos = len ; pos >= ; pos--){
int u = ;
for(int i = pos, wordLen = ; i < len; i++, wordLen++){
int c = tree.idx(in[i]);
if(tree.ch[u][c] == ) break;
u = tree.ch[u][c];
if(tree.val[u] != ){
dp[pos] += dp[pos + wordLen];
dp[pos] %= mod;
}
}
}
printf("Case %d: %lld\n", kase++, dp[]);
} return ;
}

记忆化搜索

#include <bits/stdc++.h>
using namespace std;
const int maxN = 2e6 + ;
const int mod = ;
char in[maxN];
int n;
struct Trie {
int ch[maxN][];
int val[maxN];
int sz;
void Init(){
sz = ;
memset(ch[], , sizeof(ch[]));
memset(val, , sizeof(val));
}
int idx(char c) {return c - 'a';}
void Insert(char *s){
int u = , n = strlen(s);
for(int i = ; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], , sizeof(ch[sz]));
val[sz] = ;
ch[u][c] = sz++;
}
u = ch[u][c];
}
val[u] = n;
} }tree; long long dp[maxN];
int dfs(int pos){
int temp = pos;
if(dp[pos] > ) return dp[pos];
int ret = ;
int adr = ;
while(tree.ch[adr][in[pos] - 'a']){
adr = tree.ch[adr][in[pos] - 'a'];
if(tree.val[adr] != ){
ret = (ret + dfs(pos + )) % mod;
}
pos ++; }
dp[temp] = ret;
return ret;
} int main(){
freopen("1.txt","r", stdin);
int ncase = ;
while(~scanf("%s", in)){
tree.Init();
scanf("%d", &n);
char word[];
for(int i = ; i < n; i++){
scanf("%s", word);
tree.Insert(word);
} int l = strlen(in);
for(int i = ;i <= l; i ++)dp[i] = ;
dp[l] = ;
printf("Case %d: %d\n",ncase ++ , dfs());
} return ;
}

UVALive - 3942 Remember the Word (Trie + DP)的更多相关文章

  1. UVA 3942 Remember the Word (Trie+DP)题解

    思路: 大白里Trie的例题,开篇就是一句很容易推出....orz 这里需要Trie+DP解决. 仔细想想我们可以得到dp[i]=sum(dp[i+len[x]]). 这里需要解释一下:dp是从最后一 ...

  2. UVA - 1401 Remember the Word(trie+dp)

    1.给一个串,在给一个单词集合,求用这个单词集合组成串,共有多少种组法. 例如:串 abcd, 单词集合 a, b, cd, ab 组合方式:2种: a,b,cd ab,cd 2.把单词集合建立字典树 ...

  3. UVALive 3942 Remember the Word 字典树+dp

    /** 题目:UVALive 3942 Remember the Word 链接:https://vjudge.net/problem/UVALive-3942 题意:给定一个字符串(长度最多3e5) ...

  4. UVALive 3942 Remember the Word(字典树+DP)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  5. UVALive 3942 Remember The Word (Tire)

    状态是DAG,因此方案用dp统计,dp[i] = sum(dp[i+len(x)]),x是以i开头的前缀且是单词,关键在于快速判断一个前缀是不是单词,可用Trie. 每一次转移的复杂度是O(maxle ...

  6. UvaLive3942(Trie + dp)

    查了半天数组越界的RE,才发现自己把ch数组放结构体里是过大的……放全局就A了. 类似区间的dp比较显然,只是用trie树做了优化,使得可以在trie树里一边走一边往上加dp值,不必枚举以前的每个位置 ...

  7. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  8. 【暑假】[实用数据结构]UVAlive 3942 Remember the Word

    UVAlive 3942 Remember the Word 题目: Remember the Word   Time Limit: 3000MS   Memory Limit: Unknown   ...

  9. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

随机推荐

  1. Vue2之页面 、js 、css分离

    在编写vue的时候,页面数据少的时候,可以将所有的js和css都可以直接写在页面上,但是页面数据多,js.css的方法和样式多的时候,都放在一个页面的时候,就显得页面vue十分的臃肿. 所以写项目的时 ...

  2. babel7中 corejs 和 corejs2 的区别

    babel7中 corejs 和 corejs2 的区别 最近在给项目升级 webpack4 和 babel7,有一些改变但是变化不大.具体过程可以参考这篇文章 webpack4:连奏中的进化.只是文 ...

  3. Netty之WebSocket和四种IO介绍

    Netty简介 一.什么是netty? 高性能 事件驱动 异步非堵塞 基于NIO的客户端,服务器端编程框架 稳定性和伸缩性 二.Netty的使用场景 高性能领域   多线程并发领域   异步通信领域 ...

  4. js正则匹配获取文件名

    //获取文件名,不带后缀 var file_name=file_path.replace(/(.*\/)*([^.]+).*/ig,"$2"); //获取文件后缀 1.var Fi ...

  5. ERwin DM Reverse Engineer 逆向工程介绍

    介绍内容:利用ERwin DM进行对本地 Oracle 数据库的逆向工程 ERwin DM Version:7.3 ERwin DM 提供两种方式的逆向工程方法,分别是基于脚本文件和基于数据库. 下面 ...

  6. Centos 7 搭建git服务器及使用gitolite控制权限

    一.安装git yum install git git --version #查看git版本 二.升级git(可选,如果之前已经安装git,需要升级git到最新版本) git clone https: ...

  7. centos7使用yum安装不了ffmpeg

    [root@localhost]# yum install ffmpeg Loaded plugins: fastestmirror Loading mirror speeds from cached ...

  8. BLL-IDAL-DAL的关系

    BLL  实现 IDAL  是一个接口 DAL 实现方法 BLL 调用IDAL 的方法 IDAL中的方法   在 DAL中必须实现 使用的方法  调用BLL的方法就可以

  9. 【Python图像特征的音乐序列生成】关于数据集的分享和样例数据

    数据集还在制作中,样例数据如下: 我将一条数据作为一行,X是ID,O代表了情感向量,S是速度,是一个很关键的参数,K是调式,M是节拍,L是基本拍.后面是ABC格式的序列,通过embedding化这些音 ...

  10. TC和脚本语言

    TC:Turbo C 集成开发环境是由Borland 公司开发的一套C 语言开发工具,它集成了程序编辑.调试.链接等多种功能.在DOS 系统时代,Turbo C 是被最广泛使用的一种PC 机应用程序开 ...