【leetcode前500】474. 一和零

套路太深了,看出是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]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值