leet code WC439์— ๋‚˜์˜จ palindrome ๋ฌธ์ œ์ด๋‹ค. ์ฃผ์š” ํฌ์ธํŠธ๋Š” 2๊ฐ€์ง€๋กœ ๋งํ•  ์ˆ˜ ์žˆ๋‹ค.

  1. subsquence ๋ฌธ์ œ๋Š” DP ๋ฐฉ๋ฒ•์„ ๋– ์˜ฌ๋ ค ๋ณผ ๊ฒƒ.
  2. ๋งŒ์•ฝ DP๋กœ ์ ‘๊ทผํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ•˜๊ณ , 2์ฐจ์› ๋ฐฐ์—ด์„ ๋‘๊ณ  DP๋ฌธ์ œ๋กœ ๊ฐ€์ •ํ–ˆ์„ ๋•Œ, bottom-up ๋ฐฉ์‹์ด๋ผ๋ฉด 2์ฐจ์› ๋ฐฐ์—ด DP์—์„œ๋Š” ๋จผ์ € ์•„๋ž˜ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์ƒ๊ฐํ•  ์ค„ ์•Œ์•„์•ผ ํ•œ๋‹ค.
DP Matrix for Palindrome Subsequence

์œ„ 2๊ฐ€์ง€ ํฌ์ธํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด ์ข€ ๋” ์‰ฝ๊ฒŒ ๋ฌธ์ œ๋ฅผ ํ’€ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

class Solution:
    def longestPalindromicSubsequence(self, s: str, k: int) -> int:
        def cost(c1, c2):
            dist = abs(ord(c1) - ord(c2))
            return min(dist, 26-dist)

        # k + 1 because we store 0 to k
        n = len(s)
        dp = [[[0 for _ in range(k+1)] for _ in range(n)] for _ in range(n)]

        for i in range(n):
            for kk in range(k+1):
                # single character is palindrome
                dp[i][i][kk] = 1
        
        for i in range(n-1, -1, -1):
            for j in range(i+1, n):
                # print("i, j", i, j)
                for kk in range(k+1):
                    if s[i] == s[j]:
                        dp[i][j][kk] = dp[i+1][j-1][kk] + 2
                    else:
                        dp[i][j][kk] = max(dp[i+1][j][kk], dp[i][j-1][kk])
                        d = cost(s[i], s[j])
                        if d <= kk:
                            dp[i][j][kk] = max(dp[i][j][kk], dp[i+1][j-1][kk-d] + 2)
        
        return dp[0][n-1][k]