Codeforces 1150D DP
题意:给你一个长度为n的字符串,有q次询问,每次询问会给字符串x的末尾添加一个字符y,或者删除字符串x末尾的字符,询问过后,要判断长度为n的字符串中是否有3个不重合的子序列,是这3个字符串。
思路:设dp[i][j][j]为3个字符串的长度分别为i, j, k时,匹配的最靠前的位置。那么就枚举是通过哪个字符串转移即可,但是这样是O(n ^ 3)的。我们注意到每次询问过后某个字符串的长度最多改变1,那么我们可以只重新计算没改变的那两维就可以了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
int Next[maxn][26], dp[255][255][255], now[26];
int a[4][300], tot[4];
char s[maxn];
int main() {
int n, m, x;
char op[5];
scanf("%d%d", &n, &m);
scanf("%s",s + 1);
for (int i = 0; i < 26; i++) {
now[i] = n + 1;
Next[n + 1][i] = n + 1;
}
for (int i = n; i >= 1; i--) {
for (int j = 0; j < 26; j++) {
Next[i][j] = now[j];
}
now[s[i] - 'a'] = i;
}
for (int i = 0; i < 26; i++)
Next[0][i] = now[i];
while(m--) {
scanf("%s", op + 1);
if(op[1] == '+') {
scanf("%d", &x);
scanf("%s", op + 1);
int y = op[1] - 'a';
a[x][++tot[x]] = y;
for (int i = (x == 1 ? tot[1] : 0); i <= tot[1]; i++)
for (int j = (x == 2 ? tot[2] : 0); j <= tot[2]; j++)
for (int k = (x == 3 ? tot[3] : 0); k <= tot[3]; k++) {
dp[i][j][k] = n + 1;
}
for (int i = (x == 1 ? tot[1] : 0); i <= tot[1]; i++)
for (int j = (x == 2 ? tot[2] : 0); j <= tot[2]; j++)
for (int k = (x == 3 ? tot[3] : 0); k <= tot[3]; k++) {
if(i) dp[i][j][k] = min(dp[i][j][k], Next[dp[i - 1][j][k]][a[1][i]]);
if(j) dp[i][j][k] = min(dp[i][j][k], Next[dp[i][j - 1][k]][a[2][j]]);
if(k) dp[i][j][k] = min(dp[i][j][k], Next[dp[i][j][k - 1]][a[3][k]]);
}
} else {
scanf("%d", &x);
tot[x]--;
}
if(dp[tot[1]][tot[2]][tot[3]] <= n) printf("YES\n");
else printf("NO\n");
}
}
Codeforces 1150D DP的更多相关文章
- codeforces#1150D. Three Religions(dp+序列自动机)
题目链接: https://codeforces.com/contest/1150/problem/D 题意: 给出长度为$n$的字符串,和$q$次询问 每次询问是,给$x$宗教增加一个字符$key$ ...
- Codeforces 1150D(字符串dp)
反思 三维的dp压根没看出来,看题解以后思路又很直观,找几道字符串dp练练才行 序列自动机和优化一维略 /* __ __ * ____| |_____| |____ * | | * | __ | * ...
- Two Melodies CodeForces - 813D (DP,技巧)
https://codeforces.com/problemset/problem/813/D dp[i][j] = 一条链以i结尾, 另一条链以j结尾的最大值 关键要保证转移时两条链不能相交 #in ...
- Consecutive Subsequence CodeForces - 977F(dp)
Consecutive Subsequence CodeForces - 977F 题目大意:输出一序列中的最大的连续数列的长度和与其对应的下标(连续是指 7 8 9这样的数列) 解题思路: 状态:把 ...
- codeforces的dp专题
1.(467C)http://codeforces.com/problemset/problem/467/C 题意:有一个长为n的序列,选取k个长度为m的子序列(子序列中不能有位置重复),求所取的k个 ...
- Codeforces 721C [dp][拓扑排序]
/* 题意:给你一个有向无环图.给一个限定t. 问从1点到n点,在不超过t的情况下,最多可以拜访几个点. 保证至少有一条路时限不超过t. 思路: 1.由无后向性我们可以知道(取决于该图是一个DAG), ...
- CodeForces 607C (DP) Hard problem
题目:这里 题意:给定n个字符串,每个字符串可以进行一项操作,就是将这个字符串交换,就是该字符串的第一个和最后一个交换,第二个和倒数第二个交换,以此类推,当然可以选择对于 该字符串进行或不进行这项操作 ...
- Codeforces 611d [DP][字符串]
/* 题意:给一个长度不超过5000的字符串,每个字符都是0到9的数字. 要求将整个字符串划分成严格递增的几个数字,并且不允许前导零. 思路: 1.很开心得发现,当我在前i个区间以后再加一个区间的时候 ...
- Codeforces 404D [DP]
/* 我是一个习惯后悔,但是没办法忍受内疚感的二货== 这题是个无脑dp,但是比赛大概20min没出...其实最后5min我好好想想简单化边界条件,可以出的. 题意: 给你一个长度为1e6的由?*01 ...
随机推荐
- Java 编程技巧之数据结构
前言: 介绍几种常见的java数据结构及应用. 使用HashSet判断主键是否存在 HashSet 实现 Set 接口,由哈希表(实际上是 HashMap )实现,但不保证 set 的迭代顺序,并允 ...
- JavaSE---main方法解读
1.概述 1.1 java程序入口:main方法 public static void main(String[] args){} a,public:java类由JVM调用,为了让JVM自由调用mai ...
- 数组(R语言)
myarray = <- array (vector, dimensions, dimnames) 例如,生成一个2*3*4的数组: dim1 <- c("A1",&q ...
- Hibernate Session 4种对象状态
站在持久化的角度.Hibernate把对象分为4中状态. 临时状态. 持久化状态.游离状态.删除状态. 1:Save()方法: //这个是验证:1:save方法使临时对象------>变成持久化 ...
- getcwd函数学习
getcwd 函数原型:char *getcwd( char *buffer, int maxlen ); 功 能:获取当前工作目录 参数说明:getcwd()会将当前工作目录的绝对路径复制到参数bu ...
- feign学习
feign集成了ribbon,只需要新建接口加注解即可 <!--feign相关--> <dependency> <groupId>org.springframewo ...
- linux系统的文件保护
一些文件在Linux下看上去可能一切正常,但当您尝试删除的时候,居然也会报错,就像下边一样: [root@linux236 root]# ls -l 1.txt-rw-r--r-- 1 root ro ...
- 2019牛客多校第四场 I题 后缀自动机_后缀数组_求两个串de公共子串的种类数
目录 求若干个串的公共子串个数相关变形题 对一个串建后缀自动机,另一个串在上面跑同时计数 广义后缀自动机 后缀数组 其他:POJ 3415 求两个串长度至少为k的公共子串数量 @(牛客多校第四场 I题 ...
- 将已有的lng lat 字段转换成point类型字段
利用拼接字符串转换point select GeomFromText(CONCAT('POINT(',lng,' ',lat,')')) from community limit 1; 插入字段到新表 ...
- 《Java技术》 第二次作业
java第二次作业 (一)学习总结 1.学习使用Eclipse关联jdk源代码,查看String类的equals()方法,截图,并学习其实现方法.举例说明equals方法和==的区别. 在Eclips ...