SSL 1813 回文词 P1435 回文字串 / [蓝桥杯 2016 省] 密码脱落

题目描述:

题目传送门


解题思路:

这里我们可以考虑回文串的两个性质:

  1. 回文串正序和倒叙是相同的。
  2. 回文串以中选取分割点,左部分正序与右部分倒序是相同的
    如:abbccbba
    左部分正序:abbc
    右部分正序:cbba
    右部分倒叙:abbc

因此我们可以从中作文章,延伸出两种解法。

性质一解法:

可以发现,若要使某个串成为回文串,那么显然要使这个串的倒序与这个串的正序相同。
那么问题就变成了:两个串长度相等,需要插入多少个字母,才能使得这个串的正序与倒序相同。

我们发现,若要使正序与倒序相同,显然两个串的公共子序列可以保留,因为公共子序列本身即是相同的。也就是说我们要插入的仅仅是公共子序列以外的字符。
如:abbbaabb
这两个串的公共子序列可以为 a ,这个公共串的长度为 1 1 1,那么很显然需要插入 l e n − 公 共 子 序 列 长 度 = 3 len-公共子序列 长度=3 len=3,即 3 3 3 个字符才能使得两串相同,即:aabbbbb

显然,若要使插入的字符最少,就要使 l e n − 公 共 子 序 列 长 度 len-公共子序列长度 len 最小,也就是说公共子序列长度要尽可能的大,因此我们就可以得到:
设最长公共子序列长度为 f f f,串的长度为 l e n len len
l e n − f len-f lenf

那么最长公共子序列可以怎么找呢,可以参考这里

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int n,ans;
string s,a=" ",b=" ";
unsigned short f[5001][5001]={0},t=0;
int main()
{
	cin>>s;
	n=s.size();
	a=s;
	reverse(s.begin(),s.end());  //将原串倒序得到第二个串
	b=s;
	for(int i=1;i<=n;i++)  //DP找最长公共子序列
	  {
	  	for(int j=1;j<=n;j++)
		  {
		  	if(a[i-1]==b[j-1])
		  	  f[i][j]=f[i-1][j-1]+1;
		  	else
		  	  f[i][j]=max(f[i-1][j],f[i][j-1]);
		  } 
	  }
	cout<<n-f[a.size()][b.size()];
	return 0;
} 

性质二解法:

性质二的中心思想和性质一 一样,但是性质二考虑的是:将原串的左右部分各插入一些字符,使得左右部分相同。
问题又回到了原问题,如何用最少的字符插入使得串1与串2相同。很显然,单个串插入的字符数是 l e n − 最 长 公 共 子 序 列 len-最长公共子序列 len

若左部分的串为 a a a,则它的长度为 l e n a len_a lena,右部分串为 b b b,则它的长度为 l e n b len_b lenb,很显然 l e n a = l e n b len_a=len_b lena=lenb。若 a a a b b b 的最长公共子序列长度为 f f f,则要在 a a a 串中插入 l e n a − f len_a-f lenaf 各字符才能使得 a = b a=b a=b;要在 b b b 串中插入 l e n b − f len_b-f lenbf 各字符才能使得 b = a b=a b=a

由于左右部分各要插入字符,因此,插入的总个数为:
2 ∗ ( l e n a − f ) 2*(len_{a}-f) 2(lenaf)


这里会又疑问,为什么性质一不用乘 2 2 2 呢?难道它不需要在两个串中同时插入吗?很显然性质一也是要在两个串中同时插入的。但是,性质一中的倒序串只是我们对正序串的一个复制,是一个不存在的虚拟串,也就是说,我们没有必要在一个不存在的倒序串中插入任何字符,只需插入在真实存在中的正序串中即可,因此也就不需要乘 2 2 2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值