答案解析,可以转化为01背包问题,但因为有两个target,所以要用到三维dp数组。
from collections import Counter
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
nums0 = []
nums1 = []
length = len(strs)
for s in strs:
nums0.append(Counter(s)['0'])
nums1.append(Counter(s)['1'])
dp = [[[0] * (n+1) for _ in range(m+1)] for _ in range(length+1)]
for i in range(1, length+1):
for j in range(m+1):
for k in range(n+1):
if j >= nums0[i-1] and k >= nums1[i-1]:
dp[i][j][k] = max(dp[i-1][j][k], dp[i-1][j-nums0[i-1]][k-nums1[i-1]]+1)
else:
dp[i][j][k] = dp[i-1][j][k]
return dp[-1][-1][-1]
同其他01背包问题一样,可以将三维dp数组替换为二维滚动dp数组,同样要注意背包遍历要倒序以防止重复添加物品。
from collections import Counter
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
nums0 = []
nums1 = []
length = len(strs)
for s in strs:
nums0.append(Counter(s)['0'])
nums1.append(Counter(s)['1'])
dp = [[0] * (n+1) for _ in range(m+1)]
for i in range(1, length+1):
for j in range(m, -1, -1):
for k in range(n, -1, -1):
if j >= nums0[i-1] and k >= nums1[i-1]:
dp[j][k] = max(dp[j][k], dp[j-nums0[i-1]][k-nums1[i-1]]+1)
else:
dp[j][k] = dp[j][k]
return dp[-1][-1]