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 }
沉迷于日日菜醒,不能自拔
posted on 2017-08-04 10:30 仰望咸鱼Orzzzz 阅读(197) 评论(0) 编辑 收藏 举报