序列自动机总结
用表示i位置后第一个j出现的位置
- 求子序列个数。
//记忆搜索
int dfs(int x)
{
if(f[x]) return f[x];
for(int i=0;i<26;i++)
if(next[x][i]) f[x]+=dfs(next[x][i]);
return ++f[x];
}
- 求两个串的公共子序列个数。
//表示目前字符是串1的第x位,串2的第y位
int dfs(int x,int y){
if(f[x][y]) return f[x][y];
for(int i=0;i<26;i++)
if(next1[x][i]&&next2[y][i])
f[x][y]+=dfs(next1[x][i],next2[y][i]);
return ++f[x][y];
}
- 求回文子序列个数。
//用序列自动机情况太多。
//区间dp
int subPalindrome(string str)
{
int len = str.length();
vector<vector<int> > dp(len, vector<int>(len,0));
for(int j=0;j<len;j++)
{
dp[j][j] = 1;
for(int i=j-1; i>=0;i--)
{
dp[i][j] = dp[i][j-1] + dp[i+1][j] - dp[i+1][j-1];
if(str[i] == str[j])
{
dp[i][j] += dp[i+1][j-1] + 1;
}
}
}
return dp[0][len-1];
}
浙公网安备 33010602011771号