牛客-合并回文子串(区间DP)

本文涉及的产品
传统型负载均衡 CLB,每月750个小时 15LCU
EMR Serverless StarRocks,5000CU*H 48000GB*H
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 牛客-合并回文子串(区间DP)

原题链接:更好的阅读体验

题目描述

输入两个字符串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[i][j]表示S[i]至S[j]所表示的子串是否是回文子串,是则为1,不是为0。这样根据S[i]是否等于S[j],可以把转移情况分为两类:

①若S[i]=S[j],那么只要S[i+1]和S[j-1]是回文子串,S[i]至S[j-1]就是回文子串;如果S[i+1]至S[j-1]不是回文子串,则S[i]至S[j]一定不是回文子串。

②若S[i]!=S[j],那S[i]至S[j]一定不是回文子串。

————————————————

版权声明:本文为CSDN博主「qq_42265608」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_42265608/article/details/89514122


现在的两个字符串可以考虑下用四维dp来维护,数据范围也足够友好。

状态转移的话跟一维的类似:

  dp[sa][ea][sb][eb]=0;
    if(a[sa]==a[ea]) dp[sa][ea][sb][eb]|=dp[sa+1][ea-1][sb][eb];
    if(b[sb]==b[eb]) dp[sa][ea][sb][eb]|=dp[sa][ea][sb+1][eb-1];
    if(a[sa]==b[eb]) dp[sa][ea][sb][eb]|=dp[sa+1][ea][sb][eb-1];
    if(a[ea]==b[sb]) dp[sa][ea][sb][eb]|=dp[sa][ea-1][sb+1][eb];

代码:

真·繁琐

#include<bits/stdc++.h>
using namespace std;
const int maxn=55;
bool dp[maxn][maxn][maxn][maxn];
///dp[i][j][k][q]表示a的i~j和b的k~q可以够成回文子串的最大长度
char a[maxn],b[maxn];
int main(){
    int t;cin>>t;
    while(t--){
        cin>>a+1>>b+1;
        int maxx=-0x3f3f3f3f;
        int lena=strlen(a+1),lenb=strlen(b+1);
        for(int la=0;la<=lena;la++)///枚举a长度
            for(int lb=0;lb<=lenb;lb++)///枚举b长度
                for(int sa=1;sa+la-1<=lena;sa++)///枚举a起点
                    for(int sb=1;sb+lb-1<=lenb;sb++){///枚举b起点
                        int ea=sa+la-1,eb=sb+lb-1;
                       // bool &x=dp[sa][ea][sb][eb];
                        if(la+lb<=1) dp[sa][ea][sb][eb]=1;
                        else{
                            dp[sa][ea][sb][eb]=0;
                            if(a[sa]==a[ea]) dp[sa][ea][sb][eb]|=dp[sa+1][ea-1][sb][eb];
                            if(b[sb]==b[eb]) dp[sa][ea][sb][eb]|=dp[sa][ea][sb+1][eb-1];
                            if(a[sa]==b[eb]) dp[sa][ea][sb][eb]|=dp[sa+1][ea][sb][eb-1];
                            if(a[ea]==b[sb]) dp[sa][ea][sb][eb]|=dp[sa][ea-1][sb+1][eb];
                        }
                        if(dp[sa][ea][sb][eb]) maxx=max(maxx,la+lb);
                    }
    printf("%d\n",maxx);
    }
    return 0;
}
相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
算法
【Leetcode-70.爬楼梯 -88.合并两个有序数组】
【Leetcode-70.爬楼梯 -88.合并两个有序数组】
37 0
|
6月前
leetcode代码记录(最大子数组和
leetcode代码记录(最大子数组和
30 2
|
6月前
【编程题-错题集】最长回文子序列(动态规划 - 区间dp)
【编程题-错题集】最长回文子序列(动态规划 - 区间dp)
|
6月前
|
算法
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
代码随想录算法训练营第五十六天 | LeetCode 647. 回文子串、516. 最长回文子序列、动态规划总结
56 1
|
6月前
leetcode代码记录(整数拆分
leetcode代码记录(整数拆分
52 0
|
人工智能 算法 C++
洛谷 P1090 合并果子(贪心)
洛谷 P1090 合并果子(贪心)
133 0
|
6月前
|
JavaScript
代码随想录 Day48 动态规划16 T647 回文子串 T516最长回文子序列
代码随想录 Day48 动态规划16 T647 回文子串 T516最长回文子序列
43 0
|
6月前
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
代码随想录Day45 动态规划13 LeetCode T1143最长公共子序列 T1135 不相交的线 T53最大子数组和
58 0
|
算法
代码随想录算法训练营第二天 | LeetCode 977.有序数组的平方、209.长度最小的子数组、59. 螺旋矩阵 II
代码随想录算法训练营第二天 | LeetCode 977.有序数组的平方、209.长度最小的子数组、59. 螺旋矩阵 II
55 0
|
机器学习/深度学习 算法
代码随想录训练营day57| 647. 回文子串 516.最长回文子序列
代码随想录训练营day57| 647. 回文子串 516.最长回文子序列