CROCMBTU 2012, Elimination Round (ACMICPC) H. Queries for Number of Palindromes 夜

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;
}
原文地址:https://www.cnblogs.com/liulangye/p/2780082.html