Codeforces Contest 1150 D Three Religions —— DP求三个子序列能否构成字符串的子序列

本文主要是介绍Codeforces Contest 1150 D Three Religions —— DP求三个子序列能否构成字符串的子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

This way

题意:

给你一个总的字符串,然后现在有三个空字符串,有q次操作,每次操作都会往三个字符串某一个字符串的末尾添加或者删除一个字符,问你这三个字符串按照他们的序列方式拼在一起能否组成总的字符串中的某一个序列。

题解:

最近脑子不好了,已经想不到三个序列如何拼成大的序列了,其实很简单,因为三个序列最大每个序列只有250的长度。
我们设dp[i][j][k]表示第一个串到第i位,第二个字符串到第j位,第三个字符串到第k位的时候在总的字符串中的最小位置。
那么当第1个字符串添加了一位的时候,我们只需要 n 2 n^2 n2做一下dp[i+1][j][k]即可。正确性:
假设现在有一个位置x满足dp[i][j][k],有另外一个位置x+a满足dp[i][j][k],那么对于下一个字符来说,x更优。
那么状态转移方程之一:

dp[i][j][k]=min(dp[i][j][k],nex[dp[i-1][j][k]+1][ss[1][i]-'a']);

为什么是dp[i-1][j][k]+1呢,如果j+1在dp[i-1][j][k]之前不是就错了吗:
在这里插入图片描述
那么这种情况再枚举到j+1且未枚举到k的时候会被记录下来,所以不会有问题

#include<bits/stdc++.h>
using namespace std;
const int N=251;
int dp[N][N][N],nex[100005][26],len[3];
char s[100005],ss[4][N];
int main()
{int n,q;scanf("%d%d%s",&n,&q,s+1);for(int i=0;i<26;i++)nex[n+1][i]=nex[n+2][i]=n+1;for(int i=n;i>=0;i--)for(int j=25;j>=0;j--)nex[i][j]=s[i]-'a'==j?i:nex[i+1][j];while(q--){char op[2];int id;scanf("%s%d",op,&id);if(op[0]=='+'){scanf("%s",op);ss[id][++len[id]]=op[0];for(int i=id==1?len[1]:0;i<=len[1];i++){for(int j=id==2?len[2]:0;j<=len[2];j++){for(int k=id==3?len[3]:0;k<=len[3];k++){dp[i][j][k]=i==0&&j==0&&k==0?0:n+1;if(i)dp[i][j][k]=min(dp[i][j][k],nex[dp[i-1][j][k]+1][ss[1][i]-'a']);if(j)dp[i][j][k]=min(dp[i][j][k],nex[dp[i][j-1][k]+1][ss[2][j]-'a']);if(k)dp[i][j][k]=min(dp[i][j][k],nex[dp[i][j][k-1]+1][ss[3][k]-'a']);}}}}elselen[id]--;if(dp[len[1]][len[2]][len[3]]<=n)printf("YES\n");elseprintf("NO\n");}return 0;
}

这篇关于Codeforces Contest 1150 D Three Religions —— DP求三个子序列能否构成字符串的子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881202

相关文章

2390.从字符串中移除星号

给你一个包含若干星号 * 的字符串 s 。 在一步操作中,你可以: 选中 s 中的一个星号。 移除星号左侧最近的那个非星号字符,并移除该星号自身。 返回移除 所有 星号之后的字符串。 注意: 生成的输入保证总是可以执行题面中描述的操作。 可以证明结果字符串是唯一的。 示例 1: 输入:s = “leet**cod*e” 输出:“lecoe” 解释:从左到右执行移除操作: 距离第 1 个

Python 字符串占位

在Python中,可以使用字符串的格式化方法来实现字符串的占位。常见的方法有百分号操作符 % 以及 str.format() 方法 百分号操作符 % name = "张三"age = 20message = "我叫%s,今年%d岁。" % (name, age)print(message) # 我叫张三,今年20岁。 str.format() 方法 name = "张三"age

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为

剑指offer(C++)--左旋转字符串

题目 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它! class Solution {public:string LeftRotateStri

PAT-1039 到底买不买(20)(字符串的使用)

题目描述 小红想买些珠子做一串自己喜欢的珠串。卖珠子的摊主有很多串五颜六色的珠串,但是不肯把任何一串拆散了卖。于是小红要你帮忙判断一下,某串珠子里是否包含了全部自己想要的珠子?如果是,那么告诉她有多少多余的珠子;如果不是,那么告诉她缺了多少珠子。为方便起见,我们用[0-9]、[a-z]、[A-Z]范围内的字符来表示颜色。例如,YrR8RrY是小红想做的珠串;那么ppRYYGrrYBR2258可以

js小题:通过字符串执行同名变量怎么做

在JavaScript中,你不能直接使用一个字符串来直接引用一个变量,因为JavaScript是一种静态类型语言(尽管它的类型在运行时可以变化),变量的名字在编译时就被确定了。但是,有几种方法可以实现类似的功能: 使用对象(或Map)来存储变量: 你可以使用一个对象来存储你的变量,然后使用字符串作为键来访问这些变量。 let myVars = { 'var1': 'Hello', 'var

代码随想录——摆动序列(Leetcode376)

题目链接 贪心 class Solution {public int wiggleMaxLength(int[] nums) {if(nums.length <= 1){return nums.length;}// 当前一对差值int cur = 0;// 前一对差值int pre = 0;// 峰值个数int res = 1;for(int i = 0; i < nums.length -

想让Python序列切片更高效?这些技巧你不可不知!

目录 1、自定义类实现切片 🍏 1.1 实现__getitem__方法 1.2 支持正负索引与步长 2、利用 collections.abc 模块 🧠 2.1 继承MutableSequence类 2.2 重写关键方法 3、使用标准库itertools.slice 🍲 3.1 itertools工具介绍 3.2 slice函数应用实例 4、通过生成器实现动态切片 🌀

linux匹配Nginx日志,某个字符开头和结尾的字符串

匹配 os=1 开头, &ip结尾的字符串 cat 2018-06-07.log | egrep -o ‘os=1.*.&ip’ 存入日志。然后使用submit 前面和后面的值去掉,剩下就是需要的字符串。 cat 2018-06-07.log | egrep -o ‘os=1.*.&ip’ >log.log

算法训练营第六十七天 | 卡码网110 字符串接龙、卡码网105 有向图的完全可达性、卡码网106 岛屿的周长

卡码网110 字符串接龙 这题一开始用的邻接表+dfs,不幸超时 #include <iostream>#include <list>#include <string>#include <vector>using namespace std;int minLen = 501;bool count(string a, string b) {int num = 0;for (int i