回文串(最长公共子序列)
一个字符串如果从左往右读和从右往左读都一样,那么这个字符串是一个回文串。例如:"abcba","abccba"。
蒜头君想通过添加字符把一个非回文字符串变成回文串。例如:"trit",可以添加一个i变成回文串"tirit"。
请你用程序计算出,对于一个给定的字符串,最少需要添加几个字符,才能变成回文串。
输入格式
输入一个长度为n(1≤n≤3000)的字符串。(字符串只包含字母)
输出格式
输出最少需要添加的字符个数,占一行。
样例输入
trit
样例输出
1
把回文串的顺序倒转后,与原串是一样的。
那么我们只要把给定的字符串顺序倒转与原串求最长公共子序列,再用字符串总长度减去最长公共子序列的长度就是相差的字符个数,也就是答案。
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 #include <ctime> 14 const int INF=0x3f3f3f3f; 15 typedef long long LL; 16 const int mod=1e9+7; 17 const double PI = acos(-1); 18 const double eps =1e-8; 19 #define Bug cout<<"---------------------"<<endl 20 const int maxn=1e5+10; 21 using namespace std; 22 23 string str1,str2; 24 int dp[3010][3010]; 25 26 int main() 27 { 28 cin>>str1; 29 str2=str1; 30 reverse(str2.begin(),str2.end()); 31 for(int i=1;i<=str1.size();i++) 32 { 33 for(int j=1;j<=str2.size();j++) 34 { 35 if(str1[i-1]==str2[j-1]) dp[i][j]=dp[i-1][j-1]+1; 36 else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 37 } 38 } 39 cout<<str1.size()-dp[str1.size()][str2.size()]<<endl; 40 return 0; 41 }
-