UVA - 10617 Again Palindrome

来源:互联网 发布:淘宝怎么推广最有效 编辑:程序博客网 时间:2024/05/19 22:51

区间dp

其实就是统计从整个字符串中取出任意数量的字符使之成为palindrom,当s[i]==s[j]时,根据容斥原理,dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]+dp[i+1][j-1]+1;其中,dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]是[i,j]区间内的长度不超过j-i的回文串,dp[i+1][j-1]是区间内的长度最长的回文串,1是指s[i]s[j]组成的回文串。

同理当s[i]!=s[j]的`时,dp[i][j]=dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]。

注意初始化dp[i][i]=1,并且2的60次方要用long long存储(比如每个字符都相同的情况)

#include<cstdio>#include<cstring>#include<algorithm>#define TYPE long longusing namespace std;const int MAX=70;TYPE dp[MAX][MAX];int main(){    int T;    char s[MAX];    scanf("%d",&T);    getchar();    while(T--){        gets(s);        int len=strlen(s);        memset(dp,0,MAX*MAX*sizeof(TYPE));        for(int i=0;i<MAX;i++)            dp[i][i]=1;        for(int i=2;i<=len;i++){            for(int j=0;j<=len-i;j++){                if(s[j]==s[j+i-1])                    dp[j][j+i-1]=dp[j][j+i-2]+dp[j+1][j+i-1]+1;                else                    dp[j][j+i-1]=dp[j][j+i-2]+dp[j+1][j+i-1]-(i==2?0:dp[j+1][j+i-2]);            }        }        printf("%lld\n",dp[0][len-1]);    }    return 0;}


0 0