CodeForces 245H Queries for Number of Palindromes (区间DP)

<题目链接>

题目大意:

给定字符串$S(|S|<=5000)$,下标由1开始。然后q个问题$(q\leq10^6)$,对于每个问题,给定L,R,回答区间[L,R]里有多少个回文串。

解题分析:

先预处理出任意区间的字符串是否是回文串,然后就是用区间DP,对每个区间,根据它的子区间的状态进行转移,这里要用到容斥的思想统计一下该区间回文子串的个数。$$dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+pali[i][j]$$

#include <bits/stdc++.h>
using namespace std;

const int N = 5e3+5;
bool pali[N][N];
int dp[N][N];
char str[N];

int main(){
    scanf("%s",str+1);
    int n=strlen(str+1);
    for(int i=1;i<=n;i++)pali[i][i]=1,dp[i][i]=1;
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            if(str[i]==str[j] && j-i==1)pali[i][j]=1;   //特判一下长度为2的区间
            else if(str[i]==str[j] && pali[i+1][j-1])pali[i][j]=1;
        }
    }//先用简单的区间DP,预处理出所有区间的子串是否是回文串
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+pali[i][j];   //用容斥进行该区间内回文子串数量的统计
        }
    }
    int q;scanf("%d",&q);
    while(q--){
        int l,r;scanf("%d%d",&l,&r);
        printf("%d\n",dp[l][r]);
    }
}

 

posted @ 2019-04-03 21:07  悠悠呦~  阅读(215)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end