套路太深了,看出是01背包了,但没想到要变成三维数组降为二维来做。
定义dp[i][j][k]为前i个字符串,能够0个数小于j,1个数小于k的集合最大元素数量。
很显然dp[i][j][k]=max{dp[i-1][j][k],dp[i-1][j-C0_i][k-C1_i]+1},其中C0_i表示当前字符串0的个数。
由01背包模板的经验,最外层可以被优化掉,因此只要考虑dp[j][k]就行了。不过要注意里面是一个双层循环。
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
cnt0,cnt1=[],[]
for s in strs:
c0=c1=0
for c in s:
if c=='0':
c0+=1
else:
c1+=1
cnt0.append(c0)
cnt1.append(c1)
dp=[[0 for _ in range(n+1)] for _ in range(m+1)]
for i in range(len(strs)):
c0,c1=cnt0[i],cnt1[i]
for j in range(m,c0-1,-1):
for k in range(n,c1-1,-1):
dp[j][k]=max(dp[j][k],dp[j-c0][k-c1]+1)
return dp[m][n]