POJ1159 Palindrome
来源:互联网 发布:数据恢复精灵绿色版 编辑:程序博客网 时间:2024/05/16 00:40
题目:http://acm.pku.edu.cn/JudgeOnline/problem?id=1159
思路:求字符串和它的反序字符串的最长子序列长度(LCS),再用字符串长度去剪掉子序列长度。
求LCS方法:DP。
****************************************以下为引用******************************************
LCS问题
LCS(最长公共子序列)问题可以简单地描述如下:
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。例如,若X={A,B,C,B,D,B,A},Y={B,D,C,A,B,A},则序列{B,C,A}是X和Y的一个公共子序列,但它不是X和Y的一个最长公共子序列。序列{B,C,B,A}也是X和Y的一个公共子序列,它的长度为4,而且它是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。
最长公共子序列问题就是给定两个序列X={x1,x2,...xm}和Y={y1,y2,...yn},找出X和Y的一个最长公共子序列。对于这个问题比较容易想到的算法是穷举,对X的所有子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列,并且在检查过程中记录最长的公共子序列。X的所有子序列都检查过后即可求出X和Y的最长公共子序列。X的每个子序列相应于下标集{1,2,...,m}的一个子集。因此,共有2^m个不同子序列,从而穷举搜索法需要指数时间。
事实上,最长公共子序列问题具有最优子结构性质:
设序列X={x1,x2,...,xm}和Y={y1,y2,...,yn}的一个最长公共子序列为Z={z1,z2,...,zk},则
1. 若xm=yn,则zk=xm=yn,且Zk-1是Xm-1和Yn-1的最长公共子序列。
2. 若xm!=yn且zk!=xm,则Z是Xm-1和Y的最长公共子序列。
3. 若xm!=yn切zk!=yn,则Z是X和Yn-1的最长公共子序列。
通过以上的结论,我们观察到——两个序列的最长公共子序列包含了这两个序列的前缀的最长公共子序列,这为我们将算法的时间复杂度降低到多项式级别埋下了伏笔,因为这两个序列的不同的前缀组合只有O(mn)个。并且,根据以上结论,我们可以得出计算Xi和Yj的最长公共子序列的长度c[i][j]的公式:
当i=0或j=0时,c[i][j]=0。当i,j>0且xi=yj时,c[i][j]=c[i-1][j-1]+1。当当i,j>0且xi!=yj时,c[i][j]=max{c[i][j-1],c[i-1][j]}。
这样一来,解决这个问题就比较容易了,通过建立递推结构,可以得出下列算法:
- for (i=1;i<=m;++m)
- c[i][0]=0;
- for (i=1;i<=n;++i)
- c[0][i]=0;
- for (i=1;i<=m;++i)
- {
- for (j=1;j<=n;++j)
- {
- if (x[i]==y[j])
- c[i][j]=c[i-1][j-1]+1;
- else if (c[i-1][j]>=c[i][j-1])
- c[i][j]=c[i-1][j];
- else
- c[i][j]=c[i][j-1];
- }
- }
X和Y的最长公共子序列的长度就存于c[m][n]中,欲求出具体的子序列,则可通过数组的值用O(m+n)的时间回推,具体的方法不再赘述。
****************************************以上为引用******************************************
本题代码:
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStreamReader;
- public class Main {
- public static void main(String[] args) throws NumberFormatException,
- IOException {
- BufferedReader read = new BufferedReader(new InputStreamReader(
- System.in));
- int len = Integer.parseInt(read.readLine());
- String s = read.readLine();
- StringBuilder b = new StringBuilder(s);
- b.reverse();
- char[] x = s.toCharArray();
- char[] y = b.toString().toCharArray();
- int[] c1 = new int[len + 1];
- int[] c2 = new int[len + 1];
- int max = 0;
- for (int i = 1; i < len + 1; i++) {
- for (int j = 1; j < len + 1; j++) {
- if (x[i - 1] == y[j - 1]) {
- c2[j] = c1[j - 1] + 1;
- } else {
- c2[j] = Math.max(c2[j - 1], c1[j]);
- }
- max = Math.max(max, c2[j]);
- }
- c1 = c2.clone();
- }
- System.out.println(len - max);
- }
- }
- POJ1159 Palindrome
- poj1159 - Palindrome
- POJ1159 Palindrome
- POJ1159--Palindrome
- POJ1159 Palindrome
- poj1159 Palindrome
- POJ1159,Palindrome
- POJ1159 Palindrome
- poj1159 Palindrome
- poj1159 Palindrome
- POJ1159 Palindrome LCS
- DP::poj1159 Palindrome
- poj1159 Palindrome (dp)
- HDU1513 && POJ1159:Palindrome(LCS)
- poj1159 Palindrome DP,lcs
- POJ1159 Palindrome 【动态规划】
- POJ1159——Palindrome
- 滚动数组 poj1159 Palindrome
- 联发笔试题目
- solaris日志
- webBrowser控件(浏览器)的简单使用及源码下载
- glFlush()函数的作用
- error C2362 goto与标签之间未初始化
- POJ1159 Palindrome
- S3C44B0X键盘的uClinux驱动程序设计
- WinForm编写的小游戏坦克大战(源码)
- 浅谈MS-SQL锁机制
- 导出excel文件
- uclinux内核中PC键盘驱动程序源码分析
- 【分享】PHP-MySQL-Bash-Perl-Python等一些经典书籍下载
- 从今天开始
- 什么是ROM、RAM、DRAM、SRAM和FLASH的区别