474一和零

题目:在计算机界中,我们总是追求用有限的资源获取最大的收益。现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每个 0 和 1 至多被使用一次。
注意: 给定 0 和 1 的数量都不会超过 100。给定字符串数组的长度不会超过 600。
链接:https://leetcode-cn.com/problems/ones-and-zeroes

法一:别人的代码  

https://leetcode-cn.com/problems/ones-and-zeroes/solution/pythonjie-jue-zhi-duo-wei-bei-bao-by-admin_user/

思路:动态规划,dp[i][j]表示使用i个0,j个1时可组成的最多的字符串,状态转移方程:dp[i][j] = max(dp[i][j], 1 + dp[ i-item_count0 ][ j-item_count1 ]),注意要倒着遍历,因为后面的要用到前面的,而前面的必须是上一次的。

写状态转移方程的关键是明白在哪些状态之间转移,这个题实际上有第三个变量,那就是k,k表示第几个字符串,每个不同的字符串都对应一个不同的dp状态,

from typing import List
class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        if len(strs) == 0:
            return 0
        dp = [[0] * (n + 1) for _ in range(m + 1)]  # 准备很多个背包
        for strs_item in strs:
            # 分别计算字符串中0和1的数量
            item_count0 = strs_item.count('0')
            item_count1 = strs_item.count('1')
            # 遍历可容纳的背包
            # 注意这里如果m大于 item_count0-1,则不会输出
            for i in range(m, item_count0 - 1, -1):  # 采取倒序
                for j in range(n, item_count1 - 1, -1):
                    dp[i][j] = max(dp[i][j], 1 + dp[i - item_count0][j - item_count1])
            print(dp)
        return dp[m][n]
if __name__ == '__main__':
    solution = Solution()
    result = solution.findMaxForm( strs = {"10", "0001", "111001", "1", "0"},  m = 5, n = 3)
    print(result)
View Code

ttt

 

posted on 2020-02-19 15:25  吃我一枪  阅读(269)  评论(0编辑  收藏  举报

导航