题目链接: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; }