题目:
In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.
For now, suppose you are a dominator of m 0s and n 1s respectively.
On the other hand, there is an array with strings consisting of only 0s and 1s.
Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s.
Each 0 and 1 can
be used at most once.
Note:
- The given numbers of
0sand1swill both not exceed100 - The size of given string array won't exceed
600.
Example 1:
Input: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3 Output: 4 Explanation: This are totally 4 strings can be formed by the using of 5 0s and 3 1s, which are “10,”0001”,”1”,”0”
Example 2:
Input: Array = {"10", "0", "1"}, m = 1, n = 1 Output: 2 Explanation: You could form "10", but then you'd have nothing left. Better form "0" and "1".
思路:
又是动态规划的一个变种。我们定义dp[i][j]表示从第0个字符串到截止当前字符串,用i个0和j个1可以构成的字符串的最大数目。那么状态转移方程是:dp[i][j] = max(dp[i - zero_num][j - one_num]),其中zero_num和one_num分别是当前字符串中0和1的数目,i <= zero_num <= m, j <= one_num <= n。需要注意的是:我们必须从后往前更新,这是因为如果从前往后更新,那么如果更新了dp[i][j],就意味着当前dp[i][j]的数量已经包含了s,那么在计算dp[i + ...][j + ...]的时候,用到的dp[i][j]是已经被更新过的(也就是包含了s的数量),所以就会导致重复计算。
算法的时间复杂度是O(l * m * n),其中l是字符串的数量。算法的空间复杂度是O(m*n)。
代码:
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (auto &s : strs) {
int numZeroes = 0, numOnes = 0;
for (auto c : s) {
if (c == '0')
numZeroes++;
else if (c == '1')
numOnes++;
}
for (int i = m; i >= numZeroes; i--) {
for (int j = n; j >= numOnes; j--) {
dp[i][j] = max(dp[i][j], dp[i - numZeroes][j - numOnes] + 1);
}
}
}
return dp[m][n];
}
};
本文介绍了一种使用动态规划解决的问题,即如何利用限定数量的0和1形成尽可能多的字符串组合。通过具体实例展示了算法的设计思路及实现过程。

被折叠的 条评论
为什么被折叠?



