标签:des style io color ar os sp for strong
| Time Limit: 3000MS | Memory Limit: 65536K | |
| Total Submissions: 53770 | Accepted: 18570 |
Description
Input
Output
Sample Input
5 Ab3bd
Sample Output
2
题意:求一个字符串变成回文串至少要添加多少个字符(可以在任意位置添加)
思路:将串s逆转得到s’ (注意strrev()会CE sad) ,然后求s和s‘的最长公共子序列(LCS) n-LCS即为答案。
很吃惊? 其实是这样的:因为s和s’的最长公共子序列肯定是回文,所以剩下的长度只需要添加n-LCS个字符既可以满足总体回文了。。想象成添加可能不好理解,可以这么想,LCS部分的字符串已经是回文了,所以我们不需要管它了,然后就是把剩余的字符插空了,举个例子,比如 Ab3bd 反转后得 s’ db3bA 所以LCS=3 (b3b) 那么剩余的两个字符分别为 A和d 现在我们依次把他们插入原串s:因为A在最左边,所以在最右边插入一个A 得Ab3bdA 然后此时的在右边数第二位,所以我们在左边数第二位插入一个d 得 Adb3bdA ok大功告成。。。
至于求LCS。。蒟蒻只会o(n*n) 然后数组要开short才能过。。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cctype>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define ll long long
#define maxn 360
#define pp pair<int,int>
#define INF 0x3f3f3f3f
#define max(x,y) ( ((x) > (y)) ? (x) : (y) )
#define min(x,y) ( ((x) > (y)) ? (y) : (x) )
using namespace std;
int n;
short dp[5005][5005]={0};
char s[5010],t[5010];
void solve()
{
for(int i=0;i<n;i++)
t[i]=s[n-i-1];
t[n]='\0';
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(s[i-1]==t[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
printf("%d\n",n-dp[n][n]);
}
int main()
{
scanf("%d",&n);
scanf("%s",s);
solve();
return 0;
}标签:des style io color ar os sp for strong
原文地址:http://blog.csdn.net/qq_16255321/article/details/41175251