1. http://poj.org/problem?id=1159
題意:給定一個字符串,求最少插入多少字符使該字符串變成迴文字符串。
分析:
方法1:先求該字符串與其逆序列的最長公共子序列LCS(該部分已經迴文),則原字符串長度減去LCS長度即爲需要插入的字符數。
方法2::(算法導論習題15.2 最長迴文子序列)
i=j時,LPS(i,j)=1;i<j時,LPS(i,j)=0;
以“BBABCBCAB”爲例:
#include<iostream>
#include<string>
using namespace std;
const int maxn=5005;
int dp[2][maxn];//滾動數組
string str;
int main()
{
int n;
cin>>n;
cin>>str;
for(int i=n-1;i>=0;i--)
{
dp[i&1][i]=1;
for(int j=i+1;j<n;j++)
if(str[i]==str[j])
dp[i&1][j]=dp[(i+1)&1][j-1]+2;
else
dp[i&1][j]=max(dp[i&1][j-1],dp[(i+1)&1][j]);
}
cout<<n-dp[0][n-1]<<endl;
return 0;
}
//輸出最長迴文子序列
void Printlps(string str, int m, int n)
{
if (m == n)
{
cout << str[m]; return;
}
if (str[m] == str[n])
{
cout << str[m];
Printlps(str, m + 1, n - 1);
cout << str[n];
}
else if (dp[m][n - 1] >= dp[m + 1][n])
Printlps(str, m, n - 1);
else Printlps(str, m + 1, n);
}
最長迴文子串
①動態規劃:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 100;
bool dp[maxn][maxn] = { 0 };
int lps(string str)
{
memset(dp, false, sizeof(dp));
int result = 0;
for (int i = str.length() - 1; i >= 0; i--)//i爲起點
{
dp[i][i] = true;
for (int j = i + 1; j < str.length(); j++)//j爲終點
{
if ((j == i + 1 || dp[i + 1][j - 1]) && str[i] == str[j])
{
dp[i][j] = true;
result = max(result, j - i + 1);
}
}
}
return result;
}
int main()
{
string str;
cin >> str;
int res = lps(str);
cout << res << endl;
getchar();
return 0;
}
Manacher算法:見分析
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 100;
int p[maxn];
char s[maxn];
int Init(string str)
{
s[0] = '$'; s[1] = '#';
for (int i = 0,j=2; i < str.length(); i++)
{
s[j++] = str[i];
s[j++] = '#';
}
return str.length() * 2 + 2;
}
int Manacher(string str)
{
int len = Init(str);
int Maxlen = 0, MaxRight = 0, pos = 0;
for (int i = 1; i < len; i++)
{
p[i] = i < MaxRight ? min(p[2 * pos - i], MaxRight - i) : 1;
while (s[i - p[i]] == s[i + p[i]]) p[i]++; //以i爲中心擴展
if (i + p[i] > MaxRight)//更新MaxRight,pos
{
MaxRight = i + p[i];
pos = i;
}
Maxlen = max(Maxlen, p[i]-1);
}
return Maxlen;
}
int main()
{
string str;
cin >> str;;
int ans=Manacher(str);
cout << ans << endl;
getchar();
return 0;
}