题目链接:http://codeforces.com/contest/245/problem/H
题意:给出一个字符串还有q个查询,输出每次查询区间内回文串的个数。例如aba->(aba,a,b,a)有4个
题解:如果遇到区间而且数又不大n*n能存下来的可以考虑一下用区间dp,然后区间dp一般都是可以通过
预处理来减少for的层数,这里可以预处理一下Is[i][j]表示i,j区间是否是回文串然后dp转移方程就显而易见了。
dp[i][j]=dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+Is[i][j];
#include <iostream>
#include <cstring>
using namespace std;
const int M = 5e3 + 10;
char s[M];
bool Is[M][M];
int dp[M][M];
int main() {
int q;
scanf("%s" , s);
int len = strlen(s);
memset(Is , false , sizeof(Is));
for(int i = 0 ; i < len ; i++) {
Is[i][i] = true;
}
for(int l = 1 ; l < len ; l++) {
for(int i = 0 ; i < len && i + l < len ; i++) {
int j = i + l;
if(s[i] == s[j]) {
if(l == 1) {
Is[i][j] = true;
}
else {
if(Is[i + 1][j - 1]) {
Is[i][j] = true;
}
}
}
}
}
memset(dp , 0 , sizeof(dp));
for(int i = 0 ; i < len ; i++) {
dp[i][i] = 1;
}
for(int l = 1 ; l < len ; l++) {
for(int i = 0 ; i < len && i + l < len ; i++) {
int j = i + l;
if(l == 1) {
dp[i][j] = dp[i][i] + dp[j][j] + Is[i][j];
}
else {
dp[i][j] = dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + Is[i][j];
}
}
}
scanf("%d" , &q);
while(q--) {
int l , r;
scanf("%d%d" , &l , &r);
printf("%d
" , dp[l - 1][r - 1]);
}
return 0;
}