Codeforces Round #427 (Div. 2)D. Palindromic characteristics(DP+回文串)

xiaoxiao2021-02-28  123

传送门

题意:

给一个字符串,问其中每一个回文子串的总价值。

回文子串的价值,定义:

1、如果是回文的则价值为1;

2、如果左半个回文部分的价值为k-1,则当前子串的价值为k。

思路:

1、dp[i][j]表示从第i个字符到第j个字符的子串价值,num[i]表示价值为i的子串的个数;

2、先枚举长度1、2的价值,再通过dp[i+1][j-1]尝试更新dp[i][j]的值;

3、由于子串的值可以累加,则还需对num[i]进行处理。

#include <bits/stdc++.h> using namespace std; #define N 5005 int dp[N][N]; char s[N]; int num[N]; int main() { scanf("%s",s); int n = strlen(s); for(int i=0;i<n;i++){ dp[i][i] = 1; } num[1] = n; for(int i=1;i<n;i++){ if(s[i]==s[i-1]) num[2]++,dp[i-1][i] = 2; //在单独枚举长度为2 } for(int i=2;i<n;i++){ for(int j=0;j+i<n;j++){ if(!dp[j+1][j+i-1]) continue; //如果不枚举长度2 则当 i==1 时 dp[j+1][j+1-1] 为 dp[j+1][j] if(s[j]!=s[j+i]) continue; dp[j][j+i] = dp[j][j+(i+1)/2-1] + 1; num[dp[j][j+i]]++; } }j for(int i=n;i>=1;i--){ num[i-1] += num[i]; } for(int i=1;i<=n;i++){ printf(i==1?"%d":" %d",num[i]); } return 0; }

转载请注明原文地址: https://www.6miu.com/read-17793.html

最新回复(0)