https://cn.vjudge.net/problem/15305/origin
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
short dp[5001][5001];
char s1[5001],s2[5001];
int main(){
int n;
while(cin>>n){
getchar();
for(int i=0;i<n;i++){
scanf("%c",&s1[i]);
s2[n-1-i]=s1[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][j]=dp[i-1][j-1]+1;
}
else{
dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
}
}
}
printf("%d\n",n-dp[n][n]);
}
}
d.求对字符串最少添加几个字符可变为回文串。
s.
法1:直接对它和它的逆序串求最长公共子序列长度len。N-len即为所求。(N为串长度)
因为,要求最少添加几个字符,我们可以先从原串中找到一个最长回文子序列,然后对于原串中不属于这个回文子序列的字符,在串中的相应位置添加一个相同的字符即可。那么需要添加的字符数量即为N-len。
最长回文串可以看作是原串中前面和后面字符的一种匹配(每个后面的字符在前面找到一个符合位置要求的与它相同的字符)。这种的回文匹配和原串与逆序串的公共子序列是一一对应的(一个回文匹配对应一个公共子序列,反之亦然),而且两者所涉及到的原串中的字符数量是相等的,也就是最长公共子序列对应最长回文串。原因陈述完毕。