連接:
Palindrome
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2430 Accepted Submission(s): 838
Problem 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
Sample Output
Source
Recommend
linle
題意:
先給你字符串的長度 N
再給你 N 個字符組成的序列,問最小多少個操做【添加一些字符】能夠將原來的序列變成迴文串
分析:
就是逆序存一下當前序列,而後求出 LCS 【最長公共子序列】
用 N 減去所求的最長公共子序列就能夠了
注意到序列很長 5000 若是用裸 dp[5000][5000] 就 MLE 了,
之前在 POJ 上作過這道題, 內存是 hdu 的兩倍,看過一篇博客是關於記憶化存儲的數組開 dp[maxn][maxn] short int 隨便就搞過去了,而後前天晚上就一直 MLE 啊Orz
完了學妹對我說 %2 開個 dp[2][5000] 就能夠過了。。。
也就是前一篇博客的滾動數組思想:
hdu 1159 Common Subsequence 【LCS 基礎入門】
當前這一行的狀態只由上一行的狀態和這一行前面的狀態肯定,因此只有記錄兩組Orz
也就是說直接把 裸的 LCS 的數組定義改爲 dp[2][maxn], 而後把裸的模板中的 i 所有 %2 就行了
最後輸出 n - dp[n%2][n]
關於滾動數組 LCS 若是有不瞭解的本身去上一篇博客看
code:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 5005;
int dp[2][maxn];
char s1[maxn], s2[maxn];
void LCS(int len1,int len2)
{
for(int i = 1; i <= len1; i++)
{
for(int j = 1; j <= len2; j++)
{
if(s1[i-1] == s2[j-1]) dp[i%2][j] = dp[(i-1)%2][j-1]+1;
else
{
int m1 = dp[(i-1)%2][j];
int m2 = dp[i%2][j-1];
dp[i%2][j] = max(m1, m2);
}
}
}
}
int main()
{
int n;
while(scanf("%d", &n) != EOF)
{
scanf("%s", s1);
for(int i = 0; i < n; i++)
s2[i] = s1[n-i-1];
memset(dp,0,sizeof(dp));
LCS(n,n);
printf("%d\n", n-dp[n%2][n]);
}
return 0;
}