poj1159
2016-01-14 20:14
141 查看
涉及算法:dp+lcs
题目大意:对于给定的字符串S,求出最少需要在S中添加多少个字符可以使S对称(我们称此事S为回文串),即从左往右看s和从右往左看S是一样的,
题目分析:两种思路
思路一:设dp[i][j]为字符串S从第个字母到第j个字母S之间的这段字符串S(i,j)需要填加的字符数,使得S(i,j)为回文串。
思路二:S中需要填加的字符数等于:S的长度-S和其逆序列S’的最长公共子序列的长度。用最长公共子序列的知识来求解
还有一个问题,因为S的长度可以高达500,那么势必需要一个5000x5000的二维数组,空间开销十分巨大,所以这里用了滚动数组来节省空间开销
代码如下:
题目大意:对于给定的字符串S,求出最少需要在S中添加多少个字符可以使S对称(我们称此事S为回文串),即从左往右看s和从右往左看S是一样的,
题目分析:两种思路
思路一:设dp[i][j]为字符串S从第个字母到第j个字母S之间的这段字符串S(i,j)需要填加的字符数,使得S(i,j)为回文串。
思路二:S中需要填加的字符数等于:S的长度-S和其逆序列S’的最长公共子序列的长度。用最长公共子序列的知识来求解
还有一个问题,因为S的长度可以高达500,那么势必需要一个5000x5000的二维数组,空间开销十分巨大,所以这里用了滚动数组来节省空间开销
代码如下:
import java.util.Scanner; public class Main_1159 { static int n; static char[] a; static short[][] dp; public static void main(String[] args) { Scanner in=new Scanner(System.in); n=in.nextInt(); String s=in.next(); a=s.toCharArray(); dp4(); } //思路一AC static void dp(){ dp=new short ; for(int i=0;i<n;i++){ for(int j=i;j>=0;j--){ dp[i][j]=0; } } //i要从右边开始j要从左边开始,这取决于转移方程:dp[i][j]=dp[i+1][j-1]; for(int i=n-2;i>=0;i--){ for(int j=i+1;j<n;j++){ if(a[i]==a[j]){ dp[i][j]=dp[i+1][j-1]; }else { dp[i][j]=(short) Math.min(dp[i+1][j]+1, dp[i][j-1]+1); } } } System.out.println(dp[0][n-1]); } //思路一+滚动数组 //dp[i][j]=dp[i+1][j-1]改写成dp[i%2][j]=dp[(i+1)%2][j-1] static int[][] dp2=new int[2][5001]; static void dp2(){ for(int i=n-1;i>=0;i--){ for(int j=0;j<n;j++){ if(i>=j){ dp2[i%2][j]=0; }else { if(a[i]==a[j]){ dp2[i%2][j]=dp2[(i+1)%2][j-1]; }else { dp2[i%2][j]=Math.min(dp2[(i+1)%2][j]+1, dp2[i%2][j-1]+1); } } } } System.out.println(dp2[0][n-1]); } <span style="white-space:pre"> </span>//思路二: //用Lcs来解dp[i][j]:表示s[0,i-1]和s'[0,j-1]的最长公共子序列,s'为s的逆序列 static char[] b=new char[5000];//b为a的逆序列 static void dp4(){ for(int i=0;i<n;i++){ b[i]=a[n-i-1]; } for(int i=0;i<=n;i++){ dp2[0][i]=0; } for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i-1]==b[j-1]){ dp2[i%2][j]=(short) (dp2[(i-1)%2][j-1]+1); }else { dp2[i%2][j]=(short) Math.max(dp2[(i-1)%2][j], dp2[i%2][j-1]); } } } System.out.println(n-dp2[n%2] ); } }
相关文章推荐
- Linux进程间通信——使用共享内存
- 说说JSON和JSONP,也许你会豁然开朗
- 设计模式之--单例模式
- Java开发常用的Linux命令
- 自定义组合控件及自定义属性
- 目录管理
- tomcat
- 数据归一化处理
- java web学习(基础篇)三 神奇的豆子——JavaBean
- Springmvc配置静态文件后,无法访问控制器
- 第五章 简单的数据查询
- eclipse编程环境搭建之一:java
- Python标准库07 信号 (signal包,部分os包)
- 集体终止合作 航空代理模式走投无路背后
- 关于45°角度地图坐标的计算原理 - LVin_A
- BigDecimal 使用方法详解
- 使用declare-styleable给自定义控件添加自定义属性
- 在tornado中使用celery实现异步任务处理之中的一个
- AngularJS学习笔记1
- vim打造成IDE