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)
ttt