CF427D(Div2) Palindromic characteristics

来源:互联网 发布:单片机中断系统流程图 编辑:程序博客网 时间:2024/06/14 12:27

CF427D(Div2) Palindromic characteristics

题目链接

这是一道区间DP题,我们可以首先标记一下是回文串的区间,然后对字符串内的每个区间依次求解就行,
这个求解过程可以使用标准的DP(区间大小依次增大,依次求解),
也可以使用记忆化搜索(不需要特定顺序,只要保证每个区间只更新一次就行),
在我的代码中,我使用的是记忆化搜索
根据题目复杂度(|S|<5000),在回文串判断上不需要使用优化算法,
朴素的O(n^2)判断就已经足够了

#include <bits/stdc++.h>const int MAXN=5000+5;bool dp1[MAXN][MAXN];int dp2[MAXN][MAXN];int kinds[MAXN];char str[MAXN];int len;//记忆化搜索int getNum(int L,int R){    if(dp2[L][R]==-1)    {        if(dp1[L][R])        {            dp2[L][R]=getNum(L,(L+R-1)/2)+1;            //增长计数            kinds[dp2[L][R]]++;            //输出测试(被更新的区间):printf("%d %d %d\n",L,R,dp2[L][R]);        }        else            dp2[L][R]=0;    }    return dp2[L][R];}int main(){    int main;    memset(kinds,0,sizeof(kinds));    memset(dp1,0,sizeof(dp1));    memset(dp2,-1,sizeof(dp2));    scanf("%s",&str);    len=strlen(str);    for(int i=0;i<len;i++)    {        dp1[i][i]=dp1[i][i-1]=true;        dp2[i][i]=dp2[i][i-1]=true;        kinds[1]++;    }    //更新数值    for(int i=0;i<len;i++)    {        int l=1;        while(i-l>=0&&i+l<len&&str[i-l]==str[i+l])        {            dp1[i-l][i+l]=true;            l++;        }        l=1;        while(i-l>=0&&i-1+l<len&&str[i-l]==str[i-1+l])        {            dp1[i-l][i-1+l]=true;            l++;        }    }    //区间搜索    for(int i=0;i<len;i++)        for(int j=i+1;j<len;j++)            getNum(i,j);    for(int i=len-1;i>=1;i--)        kinds[i]+=kinds[i+1];     //输出答案    for(int i=1;i<=len;i++)    {        if(i==len)            printf("%d\n",kinds[i]);        else            printf("%d ",kinds[i]);    }}
阅读全文
1 0