题意:给出一串字符串,然后m个询问,每个询问是一个区间,
求区间内有多少个回文子串;
思路:挺不错DP题,这道题需要DP两部分,判断回文和求区间
内的回文数;做的时候,只推出了求区间回文数那个状态转移
方程,判断回文那个没想到也是DP,用的是朴素的判断回文方法
超时了好多次。。。能推出一个觉得还不错,看别人的代码也看懂
了判断回文的DP,希望能跟得住节奏吧!
列个状态转移方程:dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+is_pal(i,j);
pal[i][j]=pal[i+1][j-1]&&(s[i]==s[j])
//author Joy
#pragma comment(linker, "/STACK:66777216")
#include<math.h>
#include<ctype.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<bitset>
#include<vector>
#include<queue>
#include<stack>
#include<list>
#include<map>
#include<set>
#define LL long long
using namespace std;
typedef struct coor
{
int x,y;
};
int nomalDay[]={0,31,28,31,30,31,30,31,31,30,31,30,31};//平年
int leapDay[]={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年
const int ARRSIZE=100100;
const int STRSIZE=100100;
const int GRIDSIZE=510;
const int MAXINF=(2<<20);
const int MININF=(~(2<<20));
inline bool upcmp(int a,int b)
{
return a<b;
}
inline bool downcmp(int a,int b)
{
return a>b;
}
//inline int getbit(int n)
//{
// return n==0?1:(int)log10(n)+1;
//}
/*--------------------分割线--------------------*/
string s;
int dp[GRIDSIZE*10][GRIDSIZE*10];
bool hs[GRIDSIZE*10][GRIDSIZE*10];
bool is_pal(int l, int r) //判断回文,记忆化搜索
{
if(hs[l][r])
return true;
return hs[l][r]=((s[l]==s[r])&&is_pal(l+1,r-1));
}
void solve()
{
int i,j,k,len=s.size();
for(i=0;i<len;i++)
{
dp[i][i]=1;
hs[i][i]=1;
hs[i][i-1]=1;
dp[i][i+1]=2;
if(s[i]==s[i+1])
dp[i][i+1]++;
}
for(k=2;k<len;k++)
{
i=0;
for(j=k;j<len;j++,i++)
{
dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1];
if(is_pal(i,j))
dp[i][j]++;
}
}
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
int l,r,m;
cin>>s>>m;
solve();
while(m--)
{
scanf("%d%d",&l,&r);
printf("%d\n",dp[l-1][r-1]);
}
return 0;
}