CF835 D DP
所有所有阶回文串的个数。对于一个k阶回文串,定义为:它的左右两侧相同且是k-1阶回文串
显然高阶回文串由低阶构成,那么枚举长度,从左到右遍历,dp[l][r]代表从l到r串最大的阶数,cnt[i]记录i阶的个数,显然转移为dp[l][r]=dp[l][r-len/2-1] + 1
/** @Date : 2017-08-12 11:24:44 * @FileName: D DP.cpp * @Platform: Windows * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair<int ,int> #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; char s[N]; int dp[5010][5010]; int cnt[5010]; int main() { while(~scanf("%s", s + 1)) { MMF(dp); MMF(cnt); int len = strlen(s + 1); for(int i = 1; i <= len; i++) { dp[i][i] = 1; if(s[i] == s[i + 1]) dp[i][i + 1] = 2, cnt[2]++, cnt[1]++; cnt[1]++; } for(int k = 3; k <= len; k++) { for(int l = 1; l + k - 1 <= len; l++) { int r = l + k - 1; if(s[l] != s[r] || !dp[l + 1][r - 1]) continue; int mid = (l + r) >> 1; dp[l][r] = dp[l][l + k/2 - 1] + 1;//边界 for(int i = 1; i <= dp[l][r]; i++) cnt[i]++; } } for(int i = 1; i <= len; i++) printf("%d%s", cnt[i], i==len?"\n":" "); } return 0; }