Manacher最長迴文子串:
本人學習鏈接:
https://www.cnblogs.com/BCOI/p/8971570.html(模板)
https://blog.csdn.net/weixin_42373330/article/details/82118694(詳解)
void init()//插入字符
{
len = strlen(s), cnt = 1;
str[0] = '!';
str[cnt] = '#';
for(int i=0;i<len;i++)
str[++cnt] = s[i], str[++cnt] = '#';
}
int manacher()
{
int pos = 0, mx = 0, ans = 0;
for(int i=1;i<=cnt;i++)
{
if(i < mx)
p[i] = min(p[pos*2-i],mx-i);
else
p[i] = 1;
while(str[i+p[i]] == str[i-p[i]])
p[i]++;
if(mx < i+p[i])
mx = i+p[i], pos = i;
ans = max(ans,p[i]-1);
}
return ans;
}
最長迴文子序列(動態規劃)
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e3+5;
int dp[maxn][maxn];
int main()
{
string str;
cin>>str;
int len=str.length();
memset(dp,0,sizeof(dp));
for(int i=len-1;i>=0;i--)
{
dp[i][i]=1;
for(int j=i+1;j<len;j++)
{
if(str[i]==str[j])
dp[i][j]=dp[i+1][j-1]+2;
else
dp[i][j]=max(dp[i][j-1],dp[i+1][j]);
}
}
cout<<dp[0][len-1]<<endl;
}
距離編輯(DP)
上式中的min()函數中的三個部分,對應三種字符操作方式:
edit[i-1][j]+1相當於給word2的最後插入了word1的最後的字符,插入操作使得edit+1,之後計算edit[i-1][j];
edit[i][j-1]+1相當於將word2的最後字符刪除,刪除操作edit+1,之後計算edit[i][j-1];
edit[i-1][j-1]+flag相當於通過將word2的最後一個字符替換爲word1的最後一個字符。flag標記替換的有效次數。