题目链接

题目

题目描述

输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变。如"abc"和"xyz"可以被组合成"axbycz"或"abxcyz"等。

我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。

需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可

输入描述

第一行一个整数T(T ≤ 50)。

接下来2T行,每两行两个字符串分别代表A,B(|A|,|B| ≤ 50),A,B的字符集为全体小写字母。

输出描述

对于每组数据输出一行一个整数表示价值最大的C的价值。

示例1

输入

2
aa
bb
a
aaaabcaa

输出

4
5

题解

知识点:区间dp。

一个字符串的最长回文子串需要一个区间dp即可,而且因为是串,那形成的回文串一定是整个区间,因此比起子序列记录长度,子串只需要记录区间可不可行即可。这道题是两个字符串,考虑二重区间dp。

设 \(dp[i][j][u][v]\) 表示为\(s_1\) 的区间 \([i,j]\) 和 \(s_2\) 的区间 \([u,v]\) 是否能组成回文子串。有转移方程:

\[dp[i][j][u][v] |{=}
\left \{
\begin{array}{l}
dp[i+1][j-1][u][v] &,l_1 \geq 2 且 s_1[i] = s_1[j]\\
dp[i+1][j][u][v-1] &,l_1 \geq 1 且 l_2 \geq 1且s_1[i] = s_2[v]\\
dp[i][j-1][u+1][v] &,l_1 \geq 1 且 l_2 \geq 1且s_2[u] = s_1[j]\\
dp[i][j][u+1][v-1] &,l_2 \geq 1 且 s_2[u] = s_2[v]\\
\end{array}
\right.
\]

因为合并子序列后相对位置不变,端点一定还是端点,枚举可能出现的新端点即可,左右端点 \([left,right]\) 分别可以出现在 \([s_1,s_1],[s_1,s_2],[s_2,s_1],[s_2,s_2]\) 。

时间复杂度 \(O(n^2m^2)\)

空间复杂度 \(O(n^2m^2)\)

代码

#include <bits/stdc++.h>
#define ll long long using namespace std; bool dp[52][52][52][52];
char s1[52], s2[52]; bool solve() {
memset(dp, 0, sizeof(dp));
cin >> s1 + 1 >> s2 + 1;
int n = strlen(s1 + 1);
int m = strlen(s2 + 1);
int ans = 0;
for (int l1 = 0;l1 <= n;l1++) {
for (int l2 = 0;l2 <= m;l2++) {
for (int i = 1, j = l1;j <= n;i++, j++) {
for (int u = 1, v = l2;v <= m;u++, v++) {
if (l1 + l2 <= 1) dp[i][j][u][v] = 1;///(0,0),(0,1),(1,0)的情况都是回文,
else {
if (l1 >= 2 && s1[i] == s1[j]) dp[i][j][u][v] |= dp[i + 1][j - 1][u][v];
if (l1 >= 1 && l2 >= 1 && s1[i] == s2[v]) dp[i][j][u][v] |= dp[i + 1][j][u][v - 1];
if (l1 >= 1 && l2 >= 1 && s2[u] == s1[j]) dp[i][j][u][v] |= dp[i][j - 1][u + 1][v];
if (l2 >= 2 && s2[u] == s2[v]) dp[i][j][u][v] |= dp[i][j][u + 1][v - 1];
}
if (dp[i][j][u][v]) ans = max(ans, l1 + l2);
}
}
}
}
cout << ans << '\n';
return true;
} int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int t = 1;
cin >> t;
while (t--) {
if (!solve()) cout << -1 << '\n';
}
return 0;
}

NC13230 合并回文子串的更多相关文章

  1. 合并回文子串(区间dp)

    链接:https://ac.nowcoder.com/acm/problem/13230来源:牛客网 题目描述 输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变.如" ...

  2. nowcoder 合并回文子串

    链接:https://www.nowcoder.com/acm/contest/6/C来源:牛客网题目输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变.如"abc&q ...

  3. 美团2017年CodeM大赛-初赛A轮 C合并回文子串

    区间dp一直写的是递归版本的, 竟然超时了, 学了一下非递归的写法. #include <iostream> #include <sstream> #include <a ...

  4. Manacher's algorithm: 最长回文子串算法

    Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abcc ...

  5. 后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

    1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a ...

  6. [leetcode]5. Longest Palindromic Substring最长回文子串

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  7. LeetCode[5] 最长的回文子串

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  8. 最长回文子串-LeetCode 5 Longest Palindromic Substring

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

  9. 最长回文子串(Longest Palindromic Substring)

    这算是一道经典的题目了,最长回文子串问题是在一个字符串中求得满足回文子串条件的最长的那一个.常见的解题方法有三种: (1)暴力枚举法,以每个元素为中心同时向左和向右出发,复杂度O(n^2): (2)动 ...

  10. lintcode最长回文子串(Manacher算法)

    题目来自lintcode, 链接:http://www.lintcode.com/zh-cn/problem/longest-palindromic-substring/ 最长回文子串 给出一个字符串 ...

随机推荐

  1. mybatis 源码学习

    本文为博主原创,未经允许不得转载:

  2. c#.net 6 实现简单爬虫几行代码实现百度搜索

    使用selenium封装的简单使用工具包 Gitee:SeleniumUtil: Selenium简化工具包,包含三个主流浏览器的一些基本操作 (gitee.com) 第一步安装爬虫工具: 在程序包管 ...

  3. AHB 局限性

    AHB's problem SoC bus 架构 AXI is used more and more 频率200M使用AHB,频率再升高就使用AXI AHB的问题 AHB协议本身限制要求较高,比如co ...

  4. C++ 语法结构--堆

    1.堆介绍 「堆 heap」是一种满足特定条件的完全二叉树,主要可分为图 8-1 所示的两种类型. 「大顶堆 max heap」:任意节点的值 其子节点的值. 「小顶堆 min heap」:任意节点的 ...

  5. HanLP — 感知机(Perceptron)

    感知机(Perceptron)是一个二类分类的线性分类模型,属于监督式学习算法.最终目的: 将不同的样本分本 感知机饮食了多个权重参数,输入的特征向量先是和对应的权重相乘,再加得到的积相加,然后将加权 ...

  6. Linux-文件用户及组管理-chown-chgrp

  7. [转帖]在Linux中切换cmake版本

    在Linux中切换cmake版本https://blog.whsir.com/post-6804.html   在Linux系统中,有时需要使用cmake进行程序编译,由于不同的Linux系统导致安装 ...

  8. SQL注入payload学习整理

    SQLserver 用的payload 0101%'and 1=(select @@version) and '%'=' GS的一个客户端参数 <add PropertyName="F ...

  9. forEach在项目中的使用

    forEach 会改变原始数组 被forEach循环的数组不能够为空 forEach会改变原始数组 value是内容 index是索引 array是你写的数组. foeEach内部是异步的哈 功能描述 ...

  10. 基于50W携程出行攻略构建事件图谱(含码源):交通工具子图谱、订酒店吃饭事件图谱等

    基于50W携程出行攻略构建事件图谱(含码源):交通工具子图谱.订酒店吃饭事件图谱等 项目构成 本项目由两个部分的组成,具体包括语料的获取以及基于语料的事件挖掘两个部分,具体项目目录包括: news_s ...