1. 程式人生 > >POJ 1159 Palindrome 動態規劃+滾動陣列

POJ 1159 Palindrome 動態規劃+滾動陣列

Palindrome
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 50689 Accepted: 17461

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

Source

題目大意:

給你一段字串,讓你求出在中間最少加入幾個字元可以讓他變成一段迴文子串。

解題思路:

假設S是一段字串,S'是S的逆串,則只需求出S與S'的最長公共子序列即可的長度即可,最後用字串的長度減去最長公共子序列的長度即是這道題目所求的加入的字母的長度。轉化為LCS即可。

關鍵是如果直接開DP[5005][5005]會MLE,所以就顯現出了動態陣列的重要性。

程式碼如下:

#include <iostream>
#define Max 5005
using namespace std;

char s1[Max],s2[Max];
int dp[2][Max];   //定義二維動態滾動陣列(本題以01行滾動)
int main()
{
	int n,i,j;
	while(cin>>n)
	{
		dp[0][0]=dp[1][0]=0; //動態陣列初始化 行開頭為全0
		for(i=1,j=n;i<=n;i++,j--)
		{
			dp[0][i]=dp[1][i]=0;  //動態陣列初始化 列開頭為全0
			char tmp;
			cin>>tmp;
			s1[i]=s2[j]=tmp;
		}

		int max_len=0;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
			{
				if(s1[i]==s2[j])
					dp[i%2][j]=dp[(i-1)%2][j-1]+1;   //如果字元相等,則繼承前一行前一列的dp值+1
				else
					dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]); //否則,取上方或左方的最大dp值

				if(max_len<dp[i%2][j])
					max_len=dp[i%2][j];
			}
        cout<<n-max_len<<endl;
	}
	return 0;
}