http://codeforces.com/contest/245/problem/H
代码及其注释:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<stack>
#include <iomanip>
using namespace std;
#define LL long long
const int INF=0x3f3f3f3f;
const int N=5002;
bool palindrome[N][N];//是否是回文
int ans[N][N];//从 l 到 r 回文的个数
char s[N];
typedef pair<int,int>palin;//回文对
queue<palin>qt;
int n;
int dp(int l,int r)
{
if(ans[l][r]!=-1)//记忆化
return ans[l][r];
if(l==r)//特判
{
if(palindrome[l][r])
ans[l][r]=1;
else
ans[l][r]=0;
return ans[l][r];
}
if(l+1==r)//特判
{
if(palindrome[l][r])
ans[l][r]=3;
else
ans[l][r]=2;
return ans[l][r];
}
ans[l][r]=dp(l,r-1)+dp(l+1,r)-dp(l+1,r-1);//关键递归公式
if(palindrome[l][r])//注意情况
++ans[l][r];
return ans[l][r];
}
int main()
{
//freopen("data.in","r",stdin);
memset(palindrome,false,sizeof(palindrome));
memset(ans,-1,sizeof(ans));
gets(s);
n=strlen(s);
for(int i=0;i<n;++i)//初始化长度为1 和 2的回文
{
palindrome[i][i]=true;
qt.push(palin(i,i));
if(i+1<n&&s[i+1]==s[i])
{
palindrome[i][i+1]=true;
qt.push(palin(i,i+1));
}
}
while(!qt.empty())//用队列找出所有回文
{
palin x=qt.front();qt.pop();
int l=x.first;
int r=x.second;
if(l-1>=0&&r+1<n&&s[l-1]==s[r+1])
{
palindrome[l-1][r+1]=true;
qt.push(palin(l-1,r+1));
}
}
int q;
scanf("%d",&q);
while(q--)
{
int l,r;
scanf("%d %d",&l,&r);
printf("%d\n",dp(l-1,r-1));
}
//cout<<ans[0][3]<<" "<<ans[1][3]<<" "<<ans[0][2]<<" "<<ans[1][2]<<endl;
return 0;
}
浙公网安备 33010602011771号