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;
}

posted on 2013-08-16 08:41  仗剑奔走天涯  阅读(286)  评论(0编辑  收藏  举报

导航