[蓝桥杯2016初赛]密码脱落
题目链接:http://oj.ecustacm.cn/problem.php?id=1288
X星球的考古学家发现了一批古代留下来的密码。这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
输入
输入存在多组测试数据,对于每组测试数据输入一行,表示现在看到的密码串(长度不大于1000)
输出
对于每组测试数据要求输出一个正整数,表示至少脱落了多少个种子。
样例输入 Copy
ABCBA
ABDCDCBABC
样例输出 Copy
0
3
思路:
因为是对称的串,也就是前面的一段和后面的一段是一样的(对称的) 那么很容易去想到把这个字符串去翻转一下,然后我们去找 翻转前的串 和 翻转后的串 它们之间的LCS就可以了
明确一下 LCS 并没有要求是连续的,它们之间可以有间隔
#include <iostream> #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <list> #define LL long long #define INF 0x3f3f3f3f #define ls nod<<1 #define rs (nod<<1)+1 const int maxn = 1e5 + 10 ; const LL mod = 20010905; int dp[1010][1010]; int main() { std::string a,b; while (std::cin >> a) { memset(dp, 0, sizeof(dp)); b = a; int len = a.length(); std::reverse(b.begin(), b.end()); for (int i = 1; i <= len; i++) { for (int j = 1; j <= len; j++) { if (a[i - 1] == b[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1; else { dp[i][j] = std::max(dp[i - 1][j], dp[i][j - 1]); } } } std::cout << len - dp[len][len] << std::endl; } return 0; }