CodeForces 835D Palindromic characteristics

题目链接(戳)http://codeforces.com/problemset/problem/835/D

题意

  给出一个字符串,求这个字符串1-strlen(str)阶回文串的数量,k阶回文串的左半部分(右半部分)是k-1阶的回文串。

题解

   预处理长度为1和2的子串,枚举区间长度len及起始下标i。如果str[i+1]-str[i+k-2]为回文串且str[i]==str[i+k-1]则以i为起点长度为len的子串为回文串,通过判定以i为起点,长度为len/2的子串的阶数来确定当前子串的最大阶数k(不是回文串阶数就当作0啦)。因为k阶的回文串也可看做k-1阶的回文串,所以1-k阶的回文串的数量++。

  通过维护dp[i][j]来维护每个串的最大阶数。

 

 1 /*=================================================================
 2 DP
 3 =================================================================*/
 4 #include <bits/stdc++.h>
 5 #define INF 0x3f3f3f3f
 6 #define debug printf("Debug============\n")
 7 using namespace std;
 8 typedef long long LL;
 9 const double eps = 1e-10;
10 const int maxn = 5000 + 100;
11 
12 char  s[maxn];
13 int dp[maxn][maxn],d[maxn];
14 int main() {
15 #ifdef ac
16     freopen("in.txt" , "r" , stdin);
17 //    freopen("out.txt" , "w" , stdout);
18 
19 #endif
20     scanf("%s",s);
21     int len=strlen(s); d[1]=len;
22     for(int i=0;i<len;++i) {
23         dp[i][i]=1;
24     }
25     for(int i=1;i<len;++i) if(s[i]==s[i-1]) {
26         dp[i-1][i]=2; d[2]++; d[1]++;
27     }
28     for(int k=3;k<=len;++k) {
29         for(int i=0;i<=len-k;++i) {
30             if(dp[i+1][i+k-2]&&s[i]==s[i+k-1]) {
31                 dp[i][i+k-1]=dp[i][i+k/2-1]+1;
32                 for(int x=1;x<=dp[i][i+k-1];++x) d[x]++;
33             }
34         }
35     }
36     for(int i=1;i<=len;++i) printf("%d ",d[i]);
37     return 0;
38 }
View Code

 

 

 

 

 

posted on 2017-08-04 10:30  仰望咸鱼Orzzzz  阅读(197)  评论(0编辑  收藏  举报

导航