添加最少字符到数组中组合成回文
来源:互联网 发布:访客网络账号密码 编辑:程序博客网 时间:2024/05/01 14:06
【问题描述】
回文词是一种对称的字符串——也就是说,一个回文词,从左到右读和从右到左读得到
的结果是一样的。任意给定一个字符串,通过插入若干字符,都可以变成一个回文词。你的
任务是写一个程序,求出将给定字符串变成回文词所需插入的最少字符数。
比如字符串“Ab3bd ”,在插入两个字符后可以变成一个回文词(“ dAb3bAd ”或
“Adb3bdA”)。然而,插入两个以下的字符无法使它变成一个回文词。
【输入文件】
第一行包含一个整数 N,表示给定字符串的长度,3<=N<=5000
第二行是一个长度为 N 的字符串,字符串由大小写字母和数字构成。
【输出文件】
一个整数,表示需要插入的最少字符数。
【输入样例】
5
Ab3bd
【输出样例】
回文词是一种对称的字符串——也就是说,一个回文词,从左到右读和从右到左读得到
的结果是一样的。任意给定一个字符串,通过插入若干字符,都可以变成一个回文词。你的
任务是写一个程序,求出将给定字符串变成回文词所需插入的最少字符数。
比如字符串“Ab3bd ”,在插入两个字符后可以变成一个回文词(“ dAb3bAd ”或
“Adb3bdA”)。然而,插入两个以下的字符无法使它变成一个回文词。
【输入文件】
第一行包含一个整数 N,表示给定字符串的长度,3<=N<=5000
第二行是一个长度为 N 的字符串,字符串由大小写字母和数字构成。
【输出文件】
一个整数,表示需要插入的最少字符数。
【输入样例】
5
Ab3bd
【输出样例】
2
分析:由于回文是向右和向左读的都是一样的,那么我们可以这样思考,建立另一个数组,该数组是原数组的反方向的,那么假设两者读的都是一样的,那么这两者就是相同的,也就是说他们两者组合成了回文,因此题目就化为了求最长公共子序列的问题了
code:
#include<stdio.h>#include<climits>#include<algorithm>#include<stack>#include<iostream>#include<cmath>#include<set>#include<vector>#include<map>#include<queue>#include<string.h>using namespace std;const int maxn=10000;int c[2][maxn];char str1[maxn];char str2[maxn];int main(void){ int n; while(scanf("%d",&n)!=EOF) { memset(c,0,sizeof(c)); getchar(); for(int i=1;i<=n;i++) { scanf("%c",&str1[i]); str2[n-i+1]=str1[i]; } int flag=1; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { if(str1[i]==str2[j]) { c[flag][j]=c[1-flag][j-1]+1; } else { c[flag][j]=max(c[flag][j-1],c[1-flag][j]); } cout<<c[flag][j]<<" "; } cout<<endl; flag=1-flag; } cout<<c[1-flag][n]<<endl; } return 0;}
滚动数组优化空间
另外我查阅资料更新本文章的另一种方案,可以模拟一下,本算法不是很难的:
通过前面的分析我们很容易想到这样的算法:
对于一个序列 S 只要看它的左右端的字符是否相同,如果相同那么就看除掉两端字符的新串
要添的字符个数了;如果不同,就在它左面添上右断的字符然后考虑去掉新序列两端的字符
后的串要添的字符。或者在右面添上左端的字符,在考虑去掉添了字符后新串左右两端字符
得到的新串要添的字符。
设计一个二维状态 opt[L,i]表示长度是 L+1,起点是 i 的序列变成回文词要添的字符的个数。
阶段就是字符的长度,决策要分类,即 S[i] 和 S[i+L]是否相等。
状态转移方程:
min(opt[L-1,i]+1, opt[L-1,i+1]+1) (s[i]<>s[i+L])
opt[L,i]=
min(opt[L-1,i]+1, opt[L-1,i+1]+1,opt[L-2,i+1]) (s[i]=s[i+L])
复杂度:
空间复杂度=状态数 O(N2)
时间复杂度=状态数 O(N2)* 转移代价 O(1)=O(N2)
由于空间复杂度较高,仍然要用滚动数组。
0 0
- 添加最少字符到数组中组合成回文
- 添加最少字符到数组中组合成回文
- POJ 1159 添加最少几个字符可以成回文
- 添加最少字符组成最长回文字串
- 添加最少字符使成为回文字符串
- 区间dp-添加最少字符成为回文串
- 添加最少字符数构成使字符串构成回文
- 添加最少的字符使字符串成为回文
- dp问题 添加最少的字符构成回文串
- 添加最少的字符使整体字符串都是回文字符串
- 一个字符串要变成回文串的需要添加的字符最少个数
- Light OJ 1258 Making Huge Palindromes 末尾添加最少字符变回文串
- POJ 1159 - Palindrome (DP 添加最少字符使s为回文串)
- 通过最长公共子串求得使得一个串变为回文串的最少添加字符
- 字符串问题---添加最少字符使字符串整体都是回文字符串
- STL学习-字符串回文判断以及实现删除字符串中重复字符最少字符
- 最少插入几个字符可构成回文串(动归+滚动数组)
- 插入最少字符成为回文串
- C# WinForm中添加用户控件
- 不可变数组NSArray和可变数组
- Nouveau源码分析(零):前言、目录
- Linux温习(一)Linux的文件属性与目录配置
- HDU 4010 LCT
- 添加最少字符到数组中组合成回文
- 错误累计
- dom4j的使用
- Oracle 11g安装图文攻略
- 互联网的精髓就是实用
- Android布局封装重用:iniclude和merge的使用
- 从零开始出发
- 2014年SACC系统架构师大会-札记
- HDU 3487 splay区间翻转切割