NYOJ-37 回文字符串 —— LCS变形

来源:互联网 发布:淘宝女装店 编辑:程序博客网 时间:2024/06/10 23:27

题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=37


题解:

一开始想从两边向中间添加字符,发现这样不是最优的。因为加入字符之后,这些原本存在的字符是离散的,所以就不能用顺序的方法去添加。

正确做法是将字符串逆过来,与原字符串求最大公共子序列。最大公共子序列即是不需要添加的字符序列,那么剩下的len-dp[len][len]就是需要添加进去的最少字符个数,使得原来的字符串刚好构成回文串。


代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <sstream>#include <algorithm>using namespace std;#define pb push_back#define mp make_pair#define ms(a, b)  memset((a), (b), sizeof(a))#define eps 0.0000001typedef long long LL;const int INF = 2e9;const LL LNF = 9e18;const int mod = 1e9+7;const int maxn = 1000+10;char s[maxn];int dp[maxn][maxn];void solve(){    scanf("%s",s);    int len = strlen(s);    for(int i = 0; i<len; i++)    {        for(int j = 0; j<len; j++)        {            if(s[i]==s[len-1-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][len]);}int main(){    int T;    scanf("%d",&T);    while(T--){        ms(dp,0);        solve();    }}


0 0
原创粉丝点击