IOI 迴文詞(最長公共子序列)

迴文詞(IOI)

Time Limit:6000MS  Memory Limit:565536K
Total Submit:253 Accepted:97

Description

迴文詞是一種對稱的字符串——也就是說,一個迴文詞,從左到右讀和從右到左讀得到的結果是一樣的。任意給定一個字符串,通過插入若干字符,都可以變成一個迴文詞。你的任務是寫一個程序,求出將給定字符串變成迴文詞所需插入的最少字符數。 
  比如字符串“Ab3bd”,在插入兩個字符後可以變成一個迴文詞(“dAb3bAd”或“Adb3bdA”)。然而,插入兩個以下的字符無法使它變成一個迴文詞。 

Input

第一行包含一個整數N,表示給定字符串的長度,3<=N<=5000 
  第二行是一個長度爲N的字符串,字符串由大小寫字母和數字構成。 

Output

一個整數,表示需要插入的最少字符數。

Sample Input

5
Ab3bd

Sample Output

2

Source

IOI 2000 



題目大意:

給你一個字符串,然後讓你求出最少加多少個字符就能構成一個迴文串。

解題思路:

首先把這個字符串進行反串,然後求原串和反串的最長公共子序列,求出來後,用串長減去最長公共子序列的長度就是答案了。

至於爲什麼答案會是這樣?其實,也是很好想的,我們有一個串比如說“Ab3bd”那麼他的反串就是“db3bA”,最長的公共子序列就是b3b。

那麼,這樣一來剩下了A和d,所以呢,有兩個字符不同,那麼一定是給左右各配置一個不同的字符,才能滿足其成爲一個迴文串。


代碼:

# include<cstdio>
# include<iostream>
# include<algorithm>
# include<cstring>
# include<string>
# include<cmath>
# include<queue>
# include<stack>
# include<set>
# include<map>

using namespace std;

# define inf 999999999
# define MAX 5000+4

int n;
char s1[MAX];
char s2[MAX];
int dp[MAX][MAX];

void solve()
{
    for ( int i = 1;i <= n;i++ )
    {
        for ( int j = 1;j <= n;j++ )
        {
            if ( s1[i] == s2[j] )
            {
                dp[i][j] = dp[i-1][j-1]+1;
            }
            else
            {
                dp[i][j] = max( dp[i-1][j],dp[i][j-1] );
            }
        }
    }
}

int main(void)
{
    while ( cin>>n )
    {
        cin>>s1+1;// s1從1開始輸入
        for ( int i = 1;i <= n;i++ )
        {
            s2[i] = s1[n+1-i];
        }
        solve();
        cout<<n-dp[n][n]<<endl;

    }


	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章