区间dp, 一般都为第一重for循环枚举长度,然后枚举区间,进行状态转移。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define INF 0x3f3f3f3f
bool c[5005][5005]={0};
int dp[5005][5005]={0};
int main()
{
char s[5005];
scanf("%s",s);
int t=strlen(s);
int i,j,k;
for(i=0;i<t;i++)
{
for(j=0;;j++)
{
if((i-j)<0||(i+j)>=t)
break;
if(s[i-j]==s[i+j])
c[i-j+1][i+j+1]=true;
else
break;
}
for(j=0;;j++)
{
if((i-j-1)<0||(i+j)>=t)
break;
if(s[i-j-1]==s[i+j])
c[i-j][i+j+1]=true;
else
break;
}
}
int q;
scanf("%d",&q);
for(i=1;i<=t;i++)
{
dp[i][i]=1;
}
for(i=2;i<=t;i++)
for(j=1;j+i-1<=t;j++)
{
k=j+i-1;
dp[j][k]=dp[j+1][k]+dp[j][k-1]-dp[j+1][k-1]+c[j][k];
}
while(q--)
{
int aa,bb;
scanf("%d%d",&aa,&bb);
printf("%d\n",dp[aa][bb]);
}
}