1. 程式人生 > >nyoj37 迴文字串 dp最長公共子序列LCS

nyoj37 迴文字串 dp最長公共子序列LCS

迴文字串

時間限制:3000 ms  |  記憶體限制:65535 KB

難度:4

輸入

第一行給出整數N(0<N<100) 接下來的N行,每行一個字串,每個字串長度不超過1000.

輸出

每行輸出所需新增的最少字元數

樣例輸入

1
Ab3bd

樣例輸出

2

描述

所謂迴文字串,就是一個字串,從左到右讀和從右到左讀是完全一樣的,比如"aba"。當然,我們給你的問題不會再簡單到判斷一個字串是不是迴文字串。現在要求你,給你一個字串,可在任意位置新增字元,最少再新增幾個字元,可以使這個字串成為迴文字串。

思路:

我們把原字串翻轉過來就得到了一個新的字串,這樣只需要求出與原字串的最長公共子序列的長度z,再用字串的長度減去這個值即可得出答案,我們用dp[ i ] [ j ]來表示截止到原字串第 i - 1 新串第 j - 1 的最長公共子序列的長度

程式碼:

#include<bits/stdc++.h>
using namespace std;
char s1[1010],s2[1010];
int dp[1010][1010];
int main()
{
    int t;
    scanf("%d",&t);
    while (t --)
    {
        scanf("%s",s1 + 1);
        int len = strlen(s1 + 1);
        for (int i = len;i >= 1;i --)
            s2[len-i+1] = s1[i];
        for (int i = 1;i <= len;i ++)
            for (int j = 1;j <= len;j ++)
            {
                if (s1[i] == s2[j])
                    dp[i+1][j+1] = dp[i][j] + 1;
                else
                    dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]);
            }
        printf("%d\n",len - dp[len+1][len+1]);
    }
    return 0;
}