You are given a string s and a positive integer k.
Select a set of non-overlapping substrings from the string s that satisfy the following conditions:
The length of each substring is at least k.
Each substring is a palindrome.
Return the maximum number of substrings in an optimal selection.
A substring is a contiguous sequence of characters within a string.
문자열 s와 양의 정수 k가 주어집니다.
문자열 s에서 다음 조건을 만족하는 서로 겹치지 않는 부분 문자열들을 선택하세요.
k 이상이어야 합니다.조건을 만족하도록 부분 문자열들을 선택했을 때, 선택할 수 있는 부분 문자열의 최대 개수를 반환하세요.
부분 문자열(substring) 이란 문자열에서 연속된 문자들의 구간을 의미합니다.
입력: s = "abaccdbbd", k = 3
출력: 2
설명:
문자열 s = "abaccdbbd"에서 "aba"와 "dbbd"를 선택할 수 있습니다.
두 부분 문자열 "aba"와 "dbbd"는 모두 팰린드롬이며, 길이가 k = 3 이상입니다.
조건을 만족하는 부분 문자열을 2개보다 많이 선택하는 것은 불가능하므로, 정답은 2입니다.
k 이상인 회문이어야 한다.개수이다.k인 회문만 찾으면 충분할까?k + 2 이상인 회문은 양 끝을 계속 제거하면서 더 짧은 회문으로 만들 수 있다.2씩 줄어들기 때문에 홀수 길이와 짝수 길이의 성질은 유지된다.k 이상인 회문이 존재한다면, 그 안에는 반드시 길이가 k 또는 k + 1인 회문이 존재한다.k와 k + 1 길이의 회문만 검사하면 된다.k 길이의 회문이 이후 문자열을 더 많이 남길 수 있지만, 실제 선택은 DP가 두 경우를 비교해서 결정한다.class Solution:
def maxPalindromes(self, s: str, k: int) -> int:
N = len(s)
def check(left: int, right: int) -> bool:
if left >= N or right >= N:
return 0
while left < right:
if s[left] != s[right]:
return 0
left, right = left + 1, right - 1
return 1
@cache
def dp(index: int) -> int:
if index >= N:
return 0
ans = dp(index + 1)
if check(index, index + k - 1):
ans = max(ans, 1 + dp(index + k))
if check(index, index + k):
ans = max(ans, 1 + dp(index + k + 1))
return ans
return dp(0)