1. 程式人生 > >1159--Palindrome(dp:回文串變形2)

1159--Palindrome(dp:回文串變形2)

orm accept iss sin des -- post memset example

Palindrome
Time Limit: 3000MS Memory Limit: 65536K
Total Submissions: 53431 Accepted: 18454

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

IOI 2000 還有一種dp的方法,dp[l][i],表示長度為l的以第i個字符開始的字符串須要多少操作。 對於長度為1的字符串,操作為0 長度為2的字符串,假設兩個字符同樣,操作為0,不同操作為1 長度為3的字符串。假設左右同樣,操作為0。左右不同,對於a[1],a[2],a[3]來說 能夠在前面添加a[3],或後面添加a[1],那麽就僅僅須要推斷剩余的兩和字符須要的操作了。

長度為4的字符串,左右同樣,那麽須要求中間的兩個字符,不同的話和長度為3的推斷方式同樣。 得到 長度為l開始為i的串能夠由, 長度為l-1開始為i的,長度為l-1開始為i+1的。或者是長度為l-2,開始為i+1的變化得到。

推出dp公式

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[3][5100] ;
char str[5100] ;
int main()
{
    int i , l , k1 , k2 , k3 , n ;
    while(scanf("%d", &n) !=EOF)
    {
        scanf("%s", str);
        for(i = n ; i >= 0 ; i--)
            str[i] = str[i-1] ;
        k1 = -1 ; k2 = 0 ; k3 = 1;
        memset(dp,0,sizeof(dp));
        for(l = 2 ; l <= n ; l++)
        {
            k3++ ;
            if(k3 == 3) k3 = 0 ;
            if(k3 == 0){ k2 = 2 ; k1 = 1 ; }
            else if( k3 == 1 ){ k2 = 0 ; k1 = 2 ; }
            else { k2 = 1 ; k1 = 0 ; }
            for(i = 1 ; i <= n-l+1 ; i++)
            {
                if( str[i] == str[i+l-1] )
                    dp[k3][i] = min( min(dp[k2][i]+1,dp[k2][i+1]+1),dp[k1][i+1] ) ;
                else
                    dp[k3][i] = min( dp[k2][i]+1 , dp[k2][i+1]+1);
            }
        }
        printf("%d\n", dp[k3][1]);
    }
    return 0;
}

1159--Palindrome(dp:回文串變形2)