题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1092
题意:中文题诶~
思路:
解法1:最坏的情况就是在原字符串的右边添加该字符串的倒序字符串咯,长度为a.size(),不难想到原字符串和其倒序字符串可能存在公共子序列,公共子序列含有的字符我们是不需要添加的(因为两边原本就有嘛).我们要使添加的字符最少,那么就是找到最大的公共子序列,再用a.size()减去公共子序列含有的字符数目就好啦,即:
ans=a.size()-lcs(a, b), 其中b为a的倒序字符串;
代码:
#include <bits/stdc++.h>
#define MAXN 1010
using namespace std; int dp[MAXN][MAXN]; int main(void){
string a, b;
cin >> a;
b=a;
reverse(b.begin(), b.end());
int len=a.size();
for(int i=; i<len; i++){
for(int j=; j<len; j++){
if(a[i]==b[j]){
dp[i+][j+]=dp[i][j]+;
}else{
dp[i+][j+]=max(dp[i+][j], dp[i][j+]);
}
}
}
cout << len-dp[len][len] << endl;
}
解法2:
我们可以用dp[i][j]存储从第i个字符开始长度为j的字符串变成会文串需要添加的最少字符,那么初始化:
dp[0][j]=0, dp[1][j]=0,长度为0,1的字符串自然是回文串啦;
状态转移方程式为:
if(a[j]==a[i+j-1] dp[i][j]=dp[i-1][j+1]
else dp[i][j]=min(dp[i-1][j], dp[i-1][j+1])+1
这些还是比较好理解的,直接上代码好了..
代码:
#include <bits/stdc++.h>
#define MAXN 1010
using namespace std; int dp[MAXN][MAXN]; //***dp[i][j]存储从第j个字符开始,长度为i的字符串变成回文串最少需要添加的字符数 int main(void){
string a;
cin >> a;
int len=a.size();
for(int i=; i<=len; i++){
for(int j=; j<len; j++){
if(a[j]==a[j+i-]){
dp[i][j]=dp[i-][j+];
}else{
dp[i][j]=min(dp[i-][j], dp[i-][j+])+;
}
}
}
cout << dp[len][] << endl;
return ;
}