其他分享
首页 > 其他分享> > cf835 D. Palindromic characteristics(dp)

cf835 D. Palindromic characteristics(dp)

作者:互联网

题意:

求原字符串s中 k阶回文串 的个数,k取遍1到|s|

k阶回文串:左半子串与右半子串相同,且左右两半都是非空 k-1 阶回文串

\(|s|\le 5000\)

思路:

\(f(l,r)\) 表示子串 \([l,r]\) 的回文阶数。初始:所有长度为1的子串都是1阶的。

从 \(f(l+1,r-1)\) 推到 \(f(l,r)\):若 \(s_l\neq s_r\) ,或 \(f(l+1,r-1)=0(l+1\le r-1)\) ,则 \(f(l,r)=0\);否则 \(f(l,r)=f(l+1,r-1)+1\)

枚举长度,然后枚举起点,\(O(n^2)\)

注意 k+1阶回文串必定也是 k阶回文串

const int N = 5005;
char s[N];
int n, f[N][N], ans[N];

signed main()
{
    scanf("%s", s + 1); n = strlen(s + 1);

    for(int i = 1; i <= n; i++) f[i][i] = 1, ans[1]++;

    for(int len = 2; len <= n; len++)
    {
        for(int l = 1; l + len - 1 <= n; l++)
        {
            int r = l + len - 1;
            if(s[l] != s[r] || l+1<=r-1 && !f[l+1][r-1]) f[l][r] = 0;
            else f[l][r] = f[l][l + len/2 - 1] + 1;

            ans[f[l][r]]++; //统计答案
        }
    }

    for(int i = n - 1; i; i--) ans[i] += ans[i+1]; //注意

    for(int i = 1; i <= n; i++) printf("%d ", ans[i]);
}

标签:子串,le,int,characteristics,枚举,cf835,长度,dp,回文
来源: https://www.cnblogs.com/wushansinger/p/15875950.html