首页 > 代码库 > POJ 1159 Palindrome(字符串变回文:LCS)
POJ 1159 Palindrome(字符串变回文:LCS)
POJ 1159 Palindrome(字符串变回文:LCS)
http://poj.org/problem?id=1159
题意:
给你一个字符串, 问你做少需要在该字符串中插入几个字符能是的它变成一个回文串.
分析:
首先把原字符串和它的逆串进行匹配, 找出最长公共子序列. 那么最长公共子序列的字符串肯定是一个回文串. 所以原串剩下的部分是不构成回文的. 我们只需要添加剩下部分的字符到对应位置, 原串自然就变成了一个回文.
所以本题的解为: n 减去 (原串与逆串的LCS长度).
令dp[i][j]==x表示串A的前i个字符与串B的前j个字符的子串的最长公共子序列LCS.
初始化: dp全为0.
状态转移:
A[i]==B[j]时: dp[i][j] = dp[i-1][j-1]+1.
A[i]!=B[j]时: dp[i][j] = max( dp[i-1][j] , dp[i][j-1] ).
最终所求: dp[n][m].
程序实现用的2维滚动数组, 如果用int[5000][5000]会超内存.
AC代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=5000+5; int n; char s1[maxn],s2[maxn]; int dp[2][maxn]; int main() { while(scanf("%d",&n)==1) { scanf("%s",s1); for(int i=0;i<n;i++) s2[i]=s1[n-1-i]; memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(s1[i-1]==s2[j-1]) dp[i%2][j]=dp[(i-1)%2][j-1]+1; else dp[i%2][j]=max(dp[(i-1)%2][j] , dp[i%2][j-1]); } printf("%d\n",n-dp[n%2][n]); } return 0; }
POJ 1159 Palindrome(字符串变回文:LCS)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。