474. 一和零
474. 一和零 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 提示: 1 <= strs.length <= 600 1 <= strs[i].length <= 100 strs[i] 仅由 '0' 和 '1' 组成 1 <= m, n <= 100 思路 首先,这是一个二维0-1背包问题,可以使用三维数组解决。 f[i][j][k]:i代表0~i的选取结果,j代表不超过j个零,k同理。 f[i][j][k]=max(dp[i−1][j][k],dp[i−1][j−当前字符串使用0的个数][k−当前字符串使用1的个数]+1) dp[i−1][j][k] 不选择当前考虑的字符串i dp[i−1][j−当前字符串使用0的个数][k−当前字符串使用1的个数]+1 选择当前考虑的字符串 初始化:为了避免分类讨论,通常多设置一行。这里可以认为,第 0 个字符串是空串。 点击展开/折叠 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 class Solution { public: int findMaxForm(vector<string>& strs, int m, int n) { int len = strs.size(); vector<vector<vector<int>>> dp(len + 1, vector<vector<int>>(m + 1, vector<int>(n + 1, 0))); for (int i = 1; i <= len; i++) { int x1 = cnum(strs[i - 1]); int x0 = strs[i - 1].size() - x1; for (int j = 0; j <= m; j++) { for (int k = 0; k <= n; k++) { dp[i][j][k] = dp[i - 1][j][k]; if (j >= x0 && k >= x1) { dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - x0][k - x1] + 1); } } } } return dp[len][m][n]; } int cnum(string s) { int cnt = 0; for (auto c : s) { if (c == '1') cnt++; } return cnt; } }; 参考 ...