poj 1109 Palindrome 最长递增子序列

PalindromeTime Limit:3000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u

SubmitStatus

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

题意:给出一个字符串,问最少添加几个字符可以使其变为回文串。

思路:我们分析一下回文串的特点,其逆序串str'与str是相同的,由于题目规定可以在任意的位置添加,那么,当str'与str不同时,我们可以先找出他们相同的部分,对于剩下不同的那部分,我们可以通过一个策略:互补。即把str特有的加到str'中,把str'特有的加到str中,这样一定可以获得一个回文串,怎么做到最少呢?仔细想想,如果不同的字符越少,那索要添加的就越少,即相同的字符越多,所要添加的就越少。因此,这个问题可以转换为一个最长公共子序列问题,该问题一般采用DP方法解决,递推方程是:


代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAXN 5010
using namespace std;

int dp[2][MAXN];

int max(int a,int b)
{
    return a>b?a:b;
}
int lcs(char *str1,char *str2,int len)
{
    int i,j,e=0;
    memset(dp,0,sizeof(dp));
    for(i=1;i<=len;i++)
    {
        e=1-e;
        for(j=1;j<=len;j++)
        {
            if(str1[i]==str2[j])
            {
                dp[e][j]=dp[1-e][j-1]+1;
            }
            else
            {
                dp[e][j]=max(dp[1-e][j],dp[e][j-1]);
            }
        }
    }
    return dp[e][len];
}


int main()
{
    int len,i,j;
    char str1[MAXN],str2[MAXN];
    while(~scanf("%d",&len))
    {
        scanf("%s",str1+1);
        str2[len]='\0';
        for(i=len,j=1;i>0;i--,j++)
            str2[i]=str1[j];
        //cout<<str1<<endl<<str2<<endl;
        printf("%d\n",len-lcs(str1,str2,len));
    }


    return 0;
}




你可能感兴趣的:(dp,poj,palindrome,最长递增子序列,1109)