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; }