合并回文子串(区间dp)
链接:https://ac.nowcoder.com/acm/problem/13230
来源:牛客网
题目描述
我们定义字符串的价值为其最长回文子串的长度(回文串表示从正反两边看完全一致的字符串,如"aba"和"xyyx")。
需要求出所有可能的C中价值最大的字符串,输出这个最大价值即可
输入描述:
第一行一个整数T(T ≤ 50)。
接下来2T行,每两行两个字符串分别代表A,B(|A|,|B| ≤ 50),A,B的字符集为全体小写字母。
输出描述:
对于每组数据输出一行一个整数表示价值最大的C的价值。
输出
4
5 解题思路:单独考虑合成的回文串,我们可以知道这个回文串一定是由字符串A,字符串B合成的,并且来自字符串A的字符相对位置没有变化,来自字符串B的字符的相对位置也没有变化。假设A【be1】【en1】为字符串A【i】(be1<=i<=en1),B【be2】【en2】
为字符串B【i】(be2<=i<=en2),如果这两个字符串能组成回文,设dp【be1】【en1】【be2】【en2】为1,回文的长度为en1-be1+1+en2-be2+1,如果不能构成回文那么dp【be1】【en1】【be2】【en2】为0。
经过分析,dp【be1】【en1】【be2】【en2】可能由四种状态转移而来。
1. dp【be1+1】【en1-1】【be2】【en2】(此时回文串的最左边的字符为A【be1】,最右边的字符为A【en1】)
2. dp【be1+1】【en1】【be2】【en2-1】 (此时回文串的最左边的字符为A【be1】,最右边的字符为B【en2】)
3.dp【be1】【en1-1】【be2+1】【en2】(此时回文串的最左边的字符为B【be2】,最右边的字符为A【en1】)
4.dp【be1】【en1】【be2+1】【en2-1】(此时回文串的最左边的字符为B【be2】,最右边的字符为B【en2】)
同时也需要注意边界的处理
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ri register int
typedef long long ll; inline ll gcd(ll i,ll j){
return j==0?i:gcd(j,i%j);
}
inline ll lcm(ll i,ll j){
return i/gcd(i,j)*j;
}
inline void output(int x){
if(x==0){putchar(48);return;}
int len=0,dg[20];
while(x>0){dg[++len]=x%10;x/=10;}
for(int i=len;i>=1;i--)putchar(dg[i]+48);
}
inline void read(int &x){
char ch=x=0;
int f=1;
while(!isdigit(ch)){
ch=getchar();
if(ch=='-'){
f=-1;
}
}
while(isdigit(ch))
x=x*10+ch-'0',ch=getchar();
x=x*f;
}
int dp[55][55][55][55];
int main(){
char st1[55],st2[55];
int t;
scanf("%d",&t);
while(t--){ scanf("%s%s",st1+1,st2+1); int len1=strlen(st1+1);
int len2=strlen(st2+1);
int ans=1;
for(int i=0;i<=len1;i++){//回文串来自st1的长度
for(int j=0;j<=len2;j++){//来自st2的长度
for(int be1=1,en1=i+be1-1;en1<=len1;be1++,en1++){//起点为be1 终点 为en1
for(int be2=1,en2=j+be2-1;en2<=len2;be2++,en2++){//起点be2 终点为 en2
dp[be1][en1][be2][en2]=0;
if((i+j)<=1){
dp[be1][en1][be2][en2]=1;//边界处理
}
else{
if(st1[be1]==st1[en1]&&(en1>0))dp[be1][en1][be2][en2]|=dp[be1+1][en1-1][be2][en2];
if(st1[be1]==st2[en2]&&(en2>0))dp[be1][en1][be2][en2]|=dp[be1+1][en1][be2][en2-1];
if(st1[en1]==st2[be2]&&(en1>0))dp[be1][en1][be2][en2]|=dp[be1][en1-1][be2+1][en2];
if(st2[be2]==st2[en2]&&(en2>0))dp[be1][en1][be2][en2]|=dp[be1][en1][be2+1][en2-1];
}
if(dp[be1][en1][be2][en2]){//st1[be1]~[en1]与st2[be2]~[en2]可组成回文串
ans=max(ans,en1-be1+en2-be2+2);
}
}
}
}
}
cout<<ans<<endl;
}
return 0;
}
合并回文子串(区间dp)的更多相关文章
- nowcoder 合并回文子串
链接:https://www.nowcoder.com/acm/contest/6/C来源:牛客网题目输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变.如"abc&q ...
- (最长回文子串 线性DP) 51nod 1088 最长回文子串
输入一个字符串Str,输出Str里最长回文子串的长度. 回文串:指aba.abba.cccbccc.aaaa这种左右对称的字符串. 串的子串:一个串的子串指此(字符)串中连续的一部分字符构成的子(字符 ...
- 最长回文子序列/最长回文子串(DP,马拉车)
字符子串和字符子序列的区别 字符字串指的是字符串中连续的n个字符:如palindrome中,pa,alind,drome等都属于它的字串 而字符子序列指的是字符串中不一定连续但先后顺序一致的n个字符: ...
- uva 10453 【回文串区间dp】
Uva 10453 题意:给定字符串,问最少插入多少个字符使其变成回文串,并任意输出一种结果. 题解:和Uva 10739类似,这里是只能增加.类似定义dp[i][j]表示子串Si...Sj变为回文串 ...
- leetcode 730. 统计不同回文子序列(区间dp,字符串)
题目链接 https://leetcode-cn.com/problems/count-different-palindromic-subsequences/ 题意 给定一个字符串,判断这个字符串中所 ...
- poj3280 Cheapest Palindrome(回文串区间dp)
https://vjudge.net/problem/POJ-3280 猛刷简单dp第一天第三题. 这个据说是[求字符串通过增减操作变成回文串的最小改动次数]的变体. 首先增减操作的实质是一样的,所以 ...
- nyoj 1023——还是回文——————【区间dp】
还是回文 时间限制:2000 ms | 内存限制:65535 KB 难度:3 描述 判断回文串很简单,把字符串变成回文串也不难.现在我们增加点难度,给出一串字符(全部是小写字母),添加或删除一 ...
- bzoj 1710: [Usaco2007 Open]Cheappal 廉价回文【区间dp】
只要发现添加一个字符和删除一个字符是等价的,就是挺裸的区间dp了 因为在当前位置加上一个字符x就相当于在他的对称位置删掉字符x,所以只要考虑删除即可,删除费用是添加和删除取min 设f[i][j]为从 ...
- 美团2017年CodeM大赛-初赛A轮 C合并回文子串
区间dp一直写的是递归版本的, 竟然超时了, 学了一下非递归的写法. #include <iostream> #include <sstream> #include <a ...
随机推荐
- [STM32F103]串口UART配置
l 串口时钟使能,GPIO时钟使能: RCC_APB2PeriphClockCmd(); l 串口复位: USART_DeInit(); 这一步不是必须的 l GPIO端口模式设置: GPIO_Ini ...
- C#绘图:带背景,拖鼠标画矩形和直线
基于 Visual Studio 2012 .net framework 4.5 效果截图: 代码: https://download.csdn.net/download/talkwah/104828 ...
- docker容器的常用操作
创建容器 [root@mydocker ~]# docker create --name test_create -ti ubuntu 1d13990eea0d3f282a0f7d5589f40e49 ...
- Oracle创建用户、授权、规则
---用户登录命令--管理员登录conn sys/oracle as sysdba;--创建用户方案必须是管理员权限--创建用户命令 create user useranme identifild b ...
- python 日期换算星期 蔡勒公式
#!/usr/bin/env python # encoding: utf-8 #coding=utf-8 date_star={ ':'星期一', ':'星期二', ':'星期三', ':'星期四' ...
- [持续交付实践] Jenkins 中国用户大会参会见闻
前言 上周日在上海召开了Jenkins中国用户大会(Jenkins User Confluence China),这应该是Jenkins在中国第一次举办吧.Jenkins的创始人Kohsuke Kaw ...
- 003.[python学习] 简单抓取豆瓣网电影信息程序
声明:本程序仅用于学习爬网页数据,不可用于其它用途. 本程序仍有很多不足之处,请读者不吝赐教. 依赖:本程序依赖BeautifulSoup4和lxml,如需正确运行,请先安装.下面是代码: #!/us ...
- JDK8 lameda表达式学习例子
lameda表达式是jdk8出的内容,作为一名老程序员,一直没接触.二次开发git上的一个开源项目,直接泪崩.于是赶紧补补课,直接上学习过程中的源码:package xx.test.lameda; i ...
- mysql查看及设置最大连接数
#查看: show variables like '%max_connections%'; #设置: set GLOBAL max_connections = 1000;
- nginx问题集锦
1.配置访问指定路径的文件 以访问/mnt/data/logs下文件为例,修改nginx.conf配置,执行命令重新加载/usr/local/nginx/sbin/nginx -s reload lo ...