LeetCode/DP심화

474. Ones and Zeroes

hyunkookim 2025. 1. 12. 19:11

474. Ones and Zeroes

 

https://youtu.be/miZ3qV04b1g?si=ieg8qGyjhzei0dQq

 

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        # memoization

        dp = {}  # 메모이제이션을 위한 딕셔너리 생성, 키는 (i, m, n), 값은 최대 부분집합 크기

        def dfs(i, m, n):
            if i == len(strs):  # 문자열 리스트를 모두 탐색했을 경우
                return 0  # 부분집합을 더 이상 추가할 수 없으므로 0 반환

            if (i, m, n) in dp:  # 이미 계산한 (i, m, n) 상태가 dp에 저장되어 있다면
                return dp[(i, m, n)]  # 저장된 값을 바로 반환하여 중복 계산 방지

            mCnt, nCnt = strs[i].count("0"), strs[i].count("1")  # 현재 문자열에서 '0'과 '1'의 개수를 계산
            dp[(i, m, n)] = dfs(i + 1, m, n)  # 현재 문자열을 포함하지 않고 다음 문자열로 넘어간 경우의 결과를 저장

            if mCnt <= m and nCnt <= n:  # 현재 문자열을 포함할 수 있는지 확인 (남은 '0'과 '1' 개수 조건 만족)
                # 포함하지 않은 경우와 포함한 경우 중 더 큰 값을 저장
                dp[(i, m, n)] = max(dp[(i, m, n)], 1 + dfs(i + 1, m - mCnt, n - nCnt))
            return dp[(i, m, n)]  # 현재 상태 (i, m, n)에 대한 결과 반환

        return dfs(0, m, n)  # 초기 상태에서 dfs 시작 (i=0, m=m, n=n)

 

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        # DP

        dp = defaultdict(int)

        for i in range(len(strs)):
            s = strs[i]
            mCnt, nCnt = s.count("0"), s.count("1")

            for m_i in range(0, m+1):
                for n_i in range(0, n+1):
                    if mCnt <= m_i and nCnt <= n_i:
                        dp[(i, m_i, n_i)] = max(dp[(i-1, m_i, n_i)], 1 + dp[(i-1, m_i-mCnt, n_i-nCnt)])
                    else:
                        dp[(i, m_i, n_i)] = dp[(i-1, m_i, n_i)]
            
        return dp[(len(strs)-1, m, n)]

 

=> 코드 최적화

class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        # DP
        dp = defaultdict(int)

        for s in strs:
            mCnt, nCnt = s.count("0"), s.count("1")

            for m_i in range(m, mCnt-1, -1):
                for n_i in range(n, nCnt-1, -1):
                    dp[(m_i, n_i)] = max(dp[(m_i, n_i)], 1 + dp[(m_i-mCnt, n_i-nCnt)])
            
        return dp[(m, n)]

'LeetCode > DP심화' 카테고리의 다른 글

2466. Count Ways To Build Good Strings  (0) 2025.01.13
2140. Solving Questions With Brainpower  (0) 2025.01.12
377. Combination Sum IV  (0) 2025.01.12
518. Coin Change II  (0) 2025.01.08
279. Perfect Squares ★★★  (0) 2025.01.08