洛谷P1435 回文子串
题目背景
IOI2000第一题
题目描述
回文词是一种对称的字符串。任意给定一个字符串,通过插入若干字符,都可以变成回文词。此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数。
比如 “Ab3bd”插入2个字符后可以变成回文词“dAb3bAd”或“Adb3bdA”,但是插入少于2个的字符无法变成回文词。
注:此问题区分大小写
输入格式
一个字符串(0<strlen<=1000)
输出格式
有且只有一个整数,即最少插入字符数
输入输出样例
输入: 输出:
Ab3bd
下面是这道题的题解:
这道题我一共有两种解法,下面我会把这两种解法都分享给大家:
第一种解法
第一种解法是用dp来解:
解题思路:这道题可以看做是一道求最长公共子序列的一道题(经典dp问题)!
为什么这么说呢,首先,回文串的特性就是正着读反着读都一样,一组对称的字符串。所以我们把这个字符串倒序放置也是和原来一样的。
这仿佛就找到了一个突破口。
正序与倒序“公共”的部分就是我们回文的部分,如果把正序与倒序公共的部分减去你就会惊奇的发现剩余的字符就是你所要添加的字符,也就是所求的正解!
找到解题思路后我们就可以开始写了,最长公共自序列问题是个经典的dp问题,
最容易想到的方法就是开个二维数组dp[i][j],i,j分别代表两种状态;
那么我们的动态转移方程应该就是if(a[i]==b[j]) dp[i][j]=dp[i-1][j-1]+1;
依此即可解出最长公共自序列,用字符串长度减去即是正解
由于我比较懒,下面有不直接粘贴代码了。
如果你想要更优的解法,就可以把二维数组变一维,不过这里就不说了(a了就行了,哪里呢么多事)
第二种解法
一样是dp。。。。。。
不过这次利用的是区间dp。
区间dp就很好理解了。
不解释原因了,直接上思路:
状态:dp[i][j]从i到j区间内最长回文子序列长度。
转移方程:dp[i][j]=dp[i+1][j-1]+2 i和k能配对
max(dp[i+1][j],dp[i][j-1]) i和k不能配对
状态:dp[i][i]=1
答案:dp[1][n]
复杂度:O(n^2)
下面是是dp部分代码:
for(int len=;len<=n;len++)
{
for(int i=;i<=n-len+;i++)
{
int j=i+len-;
if(a[i]==a[j])
dp[i][j]=dp[i+][j-]+;
else
dp[i][j]=max(dp[i+][j],dp[i][j-]);
}
}
输入问题注意从a[1]开始输入
输出要用总长度-回文长度
下面是全部代码(区间dp)
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define inf 100000000
//状态:dp[i][j]从i到j区间内最长回文子序列长度。
//转移方程:dp[i][j]=dp[i+1][j-1]+2 i和k能配对
// max(dp[i+1][j],dp[i][j-1]) i和k不能配对
//状态:dp[i][i]=1
//答案:dp[1][n]
//复杂度:O(n^2)
char a[];
int dp[][];
using namespace std;
int main()
{
scanf("%s",a+);
int n=strlen(a+);
for(int i=;i<=n;i++)
{
dp[i][i]=;
}
for(int len=;len<=n;len++)
{
for(int i=;i<=n-len+;i++)
{
int j=i+len-;
if(a[i]==a[j])
dp[i][j]=dp[i+][j-]+;
else
dp[i][j]=max(dp[i+][j],dp[i][j-]);
}
}
cout<<n-dp[][n];
return ;//不写return 0,考试就爆零
}
最后祝大家AC所有题!
给个赞再走呗?
洛谷P1435 回文子串的更多相关文章
- 洛谷 P1217 回文质数
洛谷 P1217 回文质数 链接 https://www.luogu.org/problem/P1217 题目 题目描述 因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 ...
- 洛谷P1217回文质数-Prime Palindrome回溯
P1217 [USACO1.5]回文质数 Prime Palindromes 题意:给定一个区间,输出其中的回文质数: 学习了洛谷大佬的回溯写法,感觉自己写回溯的能力不是很强: #include &l ...
- 洛谷 P1015 回文数 Label:续命模拟QAQ
题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. 例如:给定一个10进制数56,将56加65(即把56从右向左读),得到121是一个回文数. 又如:对于10进制数 ...
- 洛谷 P1015 回文数
#include<iostream> #include<cstdio> #include<cmath> #include<string> #includ ...
- 洛谷P1435 回文字串(dp)
题意 题目链接 回文词是一种对称的字符串.任意给定一个字符串,通过插入若干字符,都可以变成回文词.此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数. 比如 “Ab3bd”插入2个字符后可 ...
- 洛谷P1435 回文字串
题目背景 IOI2000第一题 题目描述 回文词是一种对称的字符串.任意给定一个字符串,通过插入若干字符,都可以变成回文词.此题的任务是,求出将给定字符串变成回文词所需要插入的最少字符数. 比如 “A ...
- 洛谷 - P1217 - 回文质数 - 枚举
https://www.luogu.org/problemnew/show/P1217 考虑暴力生成所有的回文数然后再判断是不是质数.注意个位的选择实际上只有4种.所以是 $4*10^3*10^3=4 ...
- 洛谷 P2010 回文日期
Noip2016普及组T2 题目描述 在日常生活中,通过年.月.日这三个要素可以表示出一个唯一确定的日期. 牛牛习惯用8位数字表示一个日期,其中,前4位代表年份,接下来2位代表月 份,最后2位代表日期 ...
- 洛谷 P2010 回文日期 题解
P2010 回文日期 题目描述 在日常生活中,通过年.月.日这三个要素可以表示出一个唯一确定的日期. 牛牛习惯用88位数字表示一个日期,其中,前44位代表年份,接下来22位代表月 份,最后22位代表日 ...
随机推荐
- (二分查找)LowerBound
在包含size个元素的,从小到大顺序的int数组a里查找比给定整数p小的,下标最大的元素,找不到返回-1 题解: int LowerBound(int a[],int size,int p) { in ...
- Python pip设置为清华镜像
设置为默认镜像 pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
- Ubantu学习笔记2
又是新的一天,继续学习Ubantu命令 cat 可以查看文件内容 cat -n p.py 可以在查看文件内容的同时显示行号 cat -s p.py 可以将多行空白的地方进行合并成一行(输入空格的地方不 ...
- 基于Ambari的WebUI部署Hive服务
基于Ambari的WebUI部署Hive服务 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.部署Ambari服务 博主推荐阅读: https://www.cnblogs.com ...
- volatile作用与处理器嗅探的简解
先贴一下 volatile 的作用定义 如果一个字段被声明成volatile,Java线程内存模型确保所有线程看到这个变量的值是一致的 首先问题就来了,一个共享变量再被volatile修饰过后,怎么被 ...
- cf 758D - Ability To Convert
从后往前贪心就好了.各种各样0的情况太BT了.. (各种爆long long,f**k) #include<bits/stdc++.h> #define LL long long #def ...
- 装WIN7的一点心得
一.为什么要装WIN7 长久以来个人的习惯,WIN10用不来,总体安装思路是:下官方版,找方法激活 二.安装镜像的来源 这个网上版本五花八门,各种系统网站,但都会有软件捆绑等行为,还有浏览器中强制捆了 ...
- 寒假day21
标签模块报了一些错误,暂时没有找出原因.刷了一些面试题
- linux_c_udp_example
udp_server #include <stdlib.h> #include <string.h> #include <unistd.h> #include &l ...
- 云平台发展前沿报告 微软云平台——Windows Azure
微软云平台——Windows Azure Windows Azure 是微软研发的公有云计算平台.该平台可供企业在互联网上运行应用,并可进行扩展.通过Windows Azure,企业能够在多个数据中心 ...