Queries for Number of Palindromes
题意:给出一个字符串,q个询问,每次询问区间[l, r]中的包含的回文串的数量;
思路:令dp[i][j]表示区间[i, j]中回文串的个数, p[i][j]表示区间[i, j]是否回文串,则dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+(p[i][j]?1:0);
#include <bits/stdc++.h>
using namespace std;
const int maxn=5010;
char s[maxn];
int dp[maxn][maxn];
const int mod=1e9+7;
int p[maxn][maxn];
//判断是否回文串;
void judge(int len){
memset(p, true, sizeof(p));//先全置为true;
for(int i=0; i<len; i++){
for(int j=i+1; j<len; j++){
p[i][j]=false;//能够表示的区间初始化为false;单个字符为true;
}
}
for(int l=2; l<=len; l++){//由区间长度递增,利用区间DP思想判断字符串是否回文
for(int i=0; i+l<=len; i++){
int j=i+l-1;
if(s[i]==s[j]&&p[i+1][j-1]) p[i][j]=true;
}
}
}
int main(){
while(~scanf("%s", s)){
memset(dp, 0, sizeof(dp));
int len=strlen(s);
judge(len);
for(int i=0; i<len; i++){
dp[i][i]=1;
}
for(int l=2; l<=len; l++){
for(int i=0; i+l<=len; i++){
int j=i+l-1;
dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+(p[i][j]?1:0);
}
}
int q;
scanf("%d", &q);
while(q--){
int l, r;
scanf("%d%d", &l, &r);
l--, r--;//题目中的字符串下标由1开始,此处由0开始;
printf("%d\n", dp[l][r]);
}
}
return 0;
}