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