最长公共子序列 & 最长不减(不增)子序列-例题题解

Poj1159

Palindrome
Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 58763   Accepted: 20419

Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome. 

As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome. 

Input

Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.

Output

Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.

Sample Input

5
Ab3bd

Sample Output

2


题意: 输出至少需要往序列中加入多少个字母才能使序列变长回文串

实际上就是n-正序逆序的最长子序列

开始想着直接输入的时候是前一半和后一半字符串的最长子序列,但是输入总有问题…就改成尝试网上的正逆串比较了~


dp[maxn][maxn]

当maxn太大时,会超出内存限制,需要改装成滚动数组【常在dp中使用】因为后面的结果就仅仅依赖于前面最近的一次结果。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define maxn 5005
using namespace std;

char S[maxn],T[maxn];
int dp[2][maxn];
int main(){
	int n;
//	freopen("1159.txt","r",stdin);
	scanf("%d",&n);
	scanf("%s",S);
	for(int i=0;i<n;i++){
		T[n-1-i]=S[i];
	}
	int e=0; 
	
	memset(dp,0,sizeof(dp));
	for(int i=0;i<n;i++){
		e=1-e;
		for(int j=0;j<n;j++){
			if(S[i]==T[j]){
				dp[e][j+1]=dp[1-e][j]+1;
			}
			else{
				dp[e][j+1]=max(dp[e][j],dp[1-e][j+1]);
			}
		}
	}
	cout<<n-dp[e][n]<<endl;
	
	return 0;
}




超水的本人,读取一半字符串的代码在下面…发现问题的麻烦联系我TT…始终不能正确写入T……


	scanf("%d",&n);
	int i;
	getchar();
	for( i=0;i<n/2;i++){
		scanf("%c",&S[i]);
	}
	
	if(n%2==0){
		scanf("%c",&S[++i]);
	} 
	else{getchar();}
	//cout<<"i="<<i<<endl;
	int j;
	for( j=0;i+j<n-1;j++){
		scanf("%d",&T[j]);
	}









你可能感兴趣的:(最长公共子序列 & 最长不减(不增)子序列-例题题解)