Codeforces245H - Queries for Number of Palindromes(区间DP)

题目大意

给定一个字符串s,q个查询,每次查询返回s[l…r]含有的回文子串个数(题目地址)

题解

和有一次多校的题目长得好相似,这个是回文子串个数,多校的是回文子序列个数

用dp[i][j]表示,s[i..j]含有的回文子串个数,则dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+flag[i][j](如果s[i..j]是回文子串则flag[i][j]=1,否则为0)

代码:

#include<iostream>

#include<cstring>

#include<cstdio>

#include<algorithm>

using namespace std;

#define MAXN 5005

int dp[MAXN][MAXN];

int flag[MAXN][MAXN],n;

char s[MAXN];

void solve(int l,int r)

{

    while(l>=1&&r<=n)

    {

        if(s[l]==s[r])

        {

            flag[l][r]=1;

            l--,r++;

        }

        else

            break;

    }

}

int main()

{

    while(scanf("%s",s+1)!=EOF)

    {

        n=strlen(s+1);

        memset(dp,0,sizeof(dp));

        memset(flag,0,sizeof(flag));

        for(int i=1; i<=n; i++)

        {

            solve(i,i);

            solve(i,i+1);

        }

        for(int i=1; i<=n; i++)

            dp[i][i]=1;

        for(int i=n; i>=1; i--)

            for(int j=i+1; j<=n; j++)

                dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+flag[i][j];

        int q;

        scanf("%d",&q);

        while(q--)

        {

            int l,r;

            scanf("%d%d",&l,&r);

            printf("%d\n",dp[l][r]);

        }

    }

    return 0;

}

你可能感兴趣的:(codeforces)