CF Round 427 D. Palindromic characteristics
题目链接:http://codeforces.com/contest/835/problem/
思路:dp[i][j]表示子串[i, j]的阶数,则:
dp[i][i] = 1;
dp[i][i + 1] = (str[i] == str[i + 1])? 2: 0;
if(str[i] != str[j] || dp[i + 1][j - 1] == 0)
dp[i][j] = 0;
else
dp[i][j] = dp[i][i + (j - i + 1) / 2 - 1] + 1;
而所有的k阶回文串必定是k - 1, k - 2....1阶回文川,因此 cnt[i] += sum(cnt[i + 1 -> len])
代码:
1 const int inf = 0x3f3f3f3f; 2 const int maxn = 5e3 + 5; 3 4 int dp[maxn][maxn], cnt[maxn]; 5 char str[maxn]; 6 7 int main(){ 8 memset(dp, 0, sizeof(dp)); 9 memset(cnt, 0, sizeof(cnt)); 10 scanf("%s", &str[1]); 11 int slen = strlen(str + 1); 12 for(int i = 1; i <= slen; i++) dp[i][i] = 1; 13 for(int i = slen - 1; i > 0; i--){ 14 dp[i][i + 1] = str[i] == str[i + 1]? 2: 0; 15 for(int j = i + 2; j <= slen; j++){ 16 if(str[i] != str[j] || dp[i + 1][j - 1] == 0) dp[i][j] = 0; 17 else dp[i][j] = dp[i][i + (j - i + 1) / 2 - 1] + 1; 18 } 19 } 20 for(int i = 1; i <= slen; i++){ 21 for(int j = i; j <= slen; j++){ 22 // debug 23 // printf("[%d, %d]: %d\n", i, j, dp[i][j]); 24 cnt[dp[i][j]]++; 25 } 26 } 27 for(int i = 1; i <= slen; i++){ 28 for(int j = i + 1; j <= slen; j++){ 29 cnt[i] += cnt[j]; 30 } 31 } 32 for(int i = 1; i <= slen; i++){ 33 printf("%d", cnt[i]); 34 if(i != slen) putchar(' '); 35 else puts(""); 36 } 37 }
题目: