题意:

给定一篇长度为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 ;
}

最新文章

  1. 30行代码让你理解angular依赖注入:angular 依赖注入原理
  2. 通达信5分钟.lc5和.lc1文件格式
  3. LeetCode OJ-- Sort List **@
  4. makefile 中 $@ $^ %&lt; 使用【转】
  5. Vigen&#232;re 密码NOIP 2012 提高组 第一天 第一题
  6. HDU 5432 Rikka with Tree (BestCoder Round #53 (div.2))
  7. Spring AOP: Spring之面向方面编程
  8. UNDO表空间损坏,爆满,ORA-600[4194]/[4193]错误解决
  9. android 读取txt文件内容
  10. 【Quick-COCOS2D-X 3.3 怎样绑定自己定义类至Lua之四】使用绑定C++至Lua的自己定义类
  11. python之---进程
  12. java将一个正整数分解质因数。例如:输入90,打印出90=2*3*3*5。
  13. leetcode — anagrams
  14. 解决新版chrome无法手动拖动安装插件 提示“无法从该网站添加应用,扩展程序和用户脚本”
  15. Linux安装gcc时碰到的有关问题解决(解决gcc依赖有关问题)
  16. LeeCX - 开源后台管理系统简单介绍
  17. Docker 配置固定IP及桥接的实现方法(转载)
  18. CXF+Spring+Hibernate实现RESTful webservice服务端实例
  19. 如何使用GCC生成动态库和静态库
  20. ASP.NET MVC提交一个较复杂对象至WCF Service

热门文章

  1. 二开获取yigo设计器里查询集合里中的某个SQL
  2. 《深入理解java虚拟机》笔记(5)垃圾回收算法及垃圾收集器
  3. 使用 xib 设置 button 等款等高
  4. Git、Github和GitLab的区别及与SVN的比较
  5. AngularJS(二):ng-app指令、表达式
  6. GreenDao 3.x 注解中ToOne和ToMany的个人理解
  7. 洛谷 P2424 约数和
  8. WPF中,DataGrid最左边多出一行的解决方案
  9. 如何从桌面程序向浏览器传递cookie或自定义header
  10. mysql 速度检索