数据结构暑假作业上出现的一题,学习了一下相关算法之后,找到了oj测试能AC。
1.回文串是一种中心对称的结构,这道题可以转变为求最长回文子序列长度的题目。(子序列:可以不连续)
2.可以得到公式: ans(最少插入字符)= 字符串总长度 - 最长回文子序列长度
3.如何求最长回文子序列的长度呢? wsx dalao的思路是对区间进行维护(我暂时还写不出来),更一般的做法是动态规划(Dynamic Programming)。
dp 粗略的可以理解为一个状态向另一个状态的转移。一个维度表示一个变量。
仔细想一下的话,很难发现最长回文子序列的长度可以变为求原字符串与其反转字符串最长公共子序列长度(LCS)的题目。
求 LCS 就可以与 dp 联系起来了。
下面列一下状态转移方程:
1 /** 2 * Night gathers, and now my watch begins. 3 * It shall not end until my death. 4 * I shall take no wife, hold no lands, father no children. 5 * I shall wear no crowns and win no glory. 6 * I shall live and die at my post. 7 * I am the sword in the darkness. 8 * I am the watcher on the walls. 9 * I am the fire that burns against the cold, 10 * the light that wakes the sleepers, 11 * the shield that guards the realms of men. 12 * I pledge my life and honor to the Night's Watch, 13 * for this night, 14 * and all the nights to come. 15 */ 16 17 #include<bits/stdc++.h> 18 #define lson i<<2 19 #define rson i<<2|1 20 #define LS l,mid,lson 21 #define RS mid+1,r,rson 22 #define mem(a,x) memset(a,x,sizeof(a)) 23 #define gcd(a,b) __gcd(a,b) 24 #define ll long long 25 #define ull unsigned long long 26 #define lowbit(x) (x&-x) 27 #define pb(x) push_back(x) 28 #define enld endl 29 #define mian main 30 #define itn int 31 #define prinft printf 32 #pragma GCC optimize(2) 33 #pragma comment(linker, "/STACK:102400000,102400000") 34 35 const double PI = acos (-1.0); 36 const int INF = 0x3f3f3f3f; 37 const int EXP = 1e-8; 38 const int N = 1e5 + 5; 39 const int MOD = 1e9 + 7; 40 const int MAXN = 1e3 + 20; 41 42 using namespace std; 43 44 string s; //题目给的原字符串 45 string sr; //原字符串的翻转字符串 46 int dp[MAXN][MAXN]; //dp[i+1][j+1]状态表示为 (s0 ~ si) 和 (s0 ~ sj) 的LCS 47 48 int main() { 49 cin >> s; 50 mem (dp, 0); //dp数组初始化 51 sr = s; 52 reverse (sr.begin(), sr.end()); //构造翻转串 53 for (itn i = 1; i <= s.size(); ++i) 54 for (int j = 1; j <= sr.size(); ++j) 55 if (s[i - 1] == sr[j - 1]) 56 dp[i][j] = dp[i - 1][j - 1] + 1; 57 else 58 dp[i][j] = max (dp[i - 1][j], dp[i][j - 1]); 59 cout << s.size() - dp[s.size()][sr.size()] << endl; //ans = s的长度 - LCS(s, sr) 60 return 0; 61 }