最大回文子序列&最大回文子串

最大回文子序列,例如cafgfkc,最大回文子序列cfgfc,输出5。子序列相当于删除某些位置上的字符后形成的序列。

最大回文子串,例如cafgfkc,最大回文子串fgf,输出3。子串相当于截取start位到end位的子串。


试过没认真看题目,原题是求子序列,想当然以为求子串,直接高高兴兴用manacher开写O(n)的实现,写正确完整后才惊喜发现是求子序列。悲剧。。


最大回文子序列: 动态规划实现。dp[i][j] 表示考虑 i 到 j 的子串时的最大回文子序列,对任何 i,dp[i][i]=1


样例输入:

cafgfkc

ksdfefrds


样例输出:

5

7


C++代码:

#include<iostream>
#include<string.h>
using namespace std;
#define rep(i,s) for(int i=0;i<s;i++)
#define mst(s,t) memset(s,t,sizeof(s))

#define MAXN 1002
int dp[MAXN][MAXN];
int len;
char str[MAXN];
int tmax(int a,int b,int c){
	a=a>b?a:b;
	a=a>c?a:c;
	return a;
}

int dpfs(int s,int t){
	if(dp[s][t]!=0||s>=t)
		return dp[s][t];
	if(str[s]==str[t])
		dp[s][t]=dpfs(s+1,t-1)+2;
	dp[s][t]=tmax(dpfs(s+1,t),dpfs(s,t-1),dp[s][t]);
	return dp[s][t];
}

int main(){
	while(cin>>str){
		mst(dp,0);
		len=strlen(str);
		for(int i=0;i<len;i++){
			dp[i][i]=1;
		}
		cout<<dpfs(0,len-1)<<endl;
	}
}



最大回文子串

样例输入:

cafgfkc

ksdfefrds


样例输出:

3

3


很久以前用java写过manacher-O(n),就直接上java代码了。其实还可以用动态规划-O(n^2),或者中心扩展法-O(n^2)(manacher是这种算法的拓展优化

java代码:

import java.util.Scanner;
public class MaxPlalindrome{
	
	static String str;
	static String str1;
	static int nlen;
	static int[] p=new int[1000001];//p[i]为以第i+1个字符为中心的最大回文数
	
	public static void main(String[] args){
		Scanner s=new Scanner(System.in);
		while(s.hasNext()){
			str=s.next();
			nlen=Proc(str);
			Manacher(str1,nlen);
			int ans=1;
			for(int i=0;i<nlen;i++){
				ans=Math.max(ans, p[i]);
			}
			System.out.println(ans-1);
		}
	}
	
	public static int Proc(String str){
		StringBuilder sk=new StringBuilder("$");
		int len=str.length();
		for(int i=0;i<len;i++){
			sk.append('#');sk.append(str.charAt(i));
		}
		sk.append('#');str1=sk.toString();
		return len*2+1;
	}
	
	public static void Manacher(String st,int len){
		int mx=0,id=0;
		for(int i=0;i<len;i++){
			p[i]=0;
		}
		//一个回文是左右对称的,那么在计算右边范围内的某个字符,
		//计算这个字符为中心的回文长度的时候,就可以利用他对称的左边的字符的回文长度
		for(int i=0;i<len;i++){
			p[i]=mx>i?Math.min(p[2*id-i], mx-i):1;
			while(i+p[i]<=len&&i-p[i]>=0&&st.charAt(i+p[i])==st.charAt(i-p[i]))
				p[i]++;
			if(i+p[i]>mx){
				mx=i+p[i];
				id=i;
			}
		}
	}
}



猜你喜欢

转载自blog.csdn.net/hqw11/article/details/51058353