Codeforces 633C Spy Syndrome 2(DP+Trie树)

题目大概说给一个加密的字符串,加密规则是把原文转化成小写字母,然后各个单词反转,最后去掉空格。现在给几个已知的单词,还原加密的字符串。

UVa1401一个道理。。

  • 用dp[i]表示加密字符前i个字符都被解密时,最后所用单词编号,为0表示不能被解密
  • 然后转移一个样,从i出发往前在Trie树上跑,看看能否找到不为0的dp[j],而str[j+1]str[j+2]...str[i-1]str[i]是单词
  • 最后输出方案就根据dp里面的值从最后面回溯找到并输出即可

时间复杂度O(加密字符串长*单词最大长度)。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 #define MAXN 1111111
 8 int tn,ch[MAXN][26],flag[MAXN];
 9 void insert(const char *s,int k){
10     int x=0,y;
11     for(int i=0; s[i]; ++i){
12         if(s[i]>=‘A‘ && s[i]<=‘Z‘) y=s[i]-‘A‘;
13         else y=s[i]-‘a‘;
14         if(ch[x][y]==0) ch[x][y]=++tn;
15         x=ch[x][y];
16     }
17     flag[x]=k;
18 }
19
20 int d[11111];
21 char str[11111];
22 string word[110000];
23 void output(int n){
24     if(n<0) return;
25     output(n-word[d[n]].length());
26     cout<<word[d[n]]<<‘ ‘;
27 }
28 int main(){
29     int n,m;
30     scanf("%d%s%d",&n,str,&m);
31     for(int i=1; i<=m; ++i){
32         cin>>word[i];
33         insert(word[i].c_str(),i);
34     }
35     for(int i=0; i<n; ++i){
36         int x=0;
37         for(int j=i; j>=0; --j){
38             int y=str[j]-‘a‘;
39             if(ch[x][y]==0) break;
40             x=ch[x][y];
41             if(flag[x] && (i-(i-j+1)<0 || d[i-(i-j+1)])){
42                 d[i]=flag[x];
43                 break;
44             }
45         }
46     }
47     output(n-1);
48     return 0;
49 }
时间: 2024-10-10 03:47:28

Codeforces 633C Spy Syndrome 2(DP+Trie树)的相关文章

[codeforces] 633C Spy Syndrome 2

原题 Trie树+dp 首先,我们可以简单的想到一种dp方式,就是如果这一段可以匹配并且可以与前一段接上,那么更新dp[i]为当前字符串的编号,然后倒推就可以得到答案. 但是,显然我们不能O(m)比较,那么怎么办呢? 这时候就可以体现Trie树的意义了,我们在爬Trie树的过程中就可以完成判断所有合法的字符串.当我们可以更新一个dp的时候就break就好了. #include<cstdio> #include<cstring> #include<vector> #def

HNU 13108 Just Another Knapsack Problem DP + Trie树优化

题意: 给你一个文本串,和一些模式串,每个模式串都有一个价值,让你选一些模式串来组成文本串,使获得的价值最大.每个模式串不止能用一次. 思路: 多重背包,枚举文本串的每个位置和模式串,把该模式串拼接在当前位置,看下一个位置是否能得到更优值.但是,存在很多模式串不能拼在当前位置的,无效状态.所以可以用Trie树来优化转移. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <c

Remember the Word,LA3942(Trie树+DP)

Trie树基础题,记录下代码. #include <cstdio> #include <cstring> #define MaxNode 4005*100 #define NodeSize 26 #define MOD 20071027 char givenword[300005]; int ans[300005]; int next[MaxNode][NodeSize]; class Trie{ public: int val[MaxNode]; int sz; Trie(){

trie树 Codeforces Round #367 D Vasiliy&#39;s Multiset

1 // trie树 Codeforces Round #367 D Vasiliy's Multiset 2 // 题意:给一个集合,初始有0,+表示添加元素,-去除元素,?询问集合里面与x异或最大的值 3 // 思路:思路很好想,建立trie树,再贪心当前位是1则选0,0则选1 4 5 6 #include <bits/stdc++.h> 7 using namespace std; 8 #define LL long long 9 const double inf = 123456789

CodeForces - 778C: Peterson Polyglot (启发式合并trie树)

Peterson loves to learn new languages, but his favorite hobby is making new ones. Language is a set of words, and word is a sequence of lowercase Latin letters. Peterson makes new language every morning. It is difficult task to store the whole langua

Codeforces 282E. Sausage Maximization【trie树(非指针版)】

题目大意: 给出一串数,pre[i](前i个数的异或)为a[0]~a[i-1]的异或,post[i](后缀的异或)为a[i]~a[n-1]的异或,求pre[i]^post[j]的最大值(0<=i<=j<=n),其中,pre[0]=0,post[n]=0(表示一个数都不选). 做法: 利用trie树将后缀或者前缀存储起来,首先从pre[n]开始,往前遍历,对于每个前缀,将此时的后缀添加到trie树中,再在trie中寻找与当前前缀异或之后能得到最大的值. 在trie中存储数的时候,将该数的二

【状压dp】Trie 树 @中山纪念中学20170304

目录 Trie 树 PROBLEM 题目描述 输入 输出 样例输入 样例输出 SOLUTION CODE Trie 树 PROBLEM 题目描述 字母(Trie)树是一个表示一个字符串集合中所有字符串的前缀的数据结构,其有如下特征: 1.树的每一条边表示字母表中的一个字母 2.树根表示一个空的前缀 3.树上所有其他的节点都表示一个非空前缀,每一个节点表示的前缀为树 根到该节点的路径上所有字母依次连接而成的字符串. 4.一个节点的所有出边(节点到儿子节点的边)中不存在重复的字母. 现在Matej手

UVaLive 3942 Remember the Word (dp+字典树)

Remember the Word DescriptionNeal is very curious about combinatorial problems, and now here comes a problem about words. Knowing that Ray has a photographic memory and this may not trouble him, Neal gives it to Jiejie. Since Jiejie can’t remember nu

ifrog-1028 Bob and Alice are playing numbers(trie树)

题目链接: Bob and Alice are playing numbers DESCRIPTION Bob and his girl friend are playing game together.This game is like this: There are nn numbers. If op = 11,Bob wants to find two numbers aiai and ajaj,that aiai & ajaj will become maximum value. If