1 题目
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
0s
and1s
will 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".
2 尝试解
2.1 分析
背包问题升级版。给定一个字符串数组,每个字符串均由0和1组成。在限定字符0和1的上限分别为m和n后,问最多能从数组中挑出多少个字符串。
背包从一维条件限制变成了二维条件限制,基本思想仍与0-1背包问题相同。
2.2 代码
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> saver(m+1,vector<int>(n+1,0));
for(int i = 0; i < strs.size();i++){
int zeros = 0;
for(auto letter:strs[i]){
zeros += (letter=='0'?1:0);
}
int ones = strs[i].size() - zeros;
for(int j = m;j >= zeros; j--){
for(int k = n; k >= ones;k--){
if(i)
saver[j][k] = max(saver[j][k],saver[j-zeros][k-ones]+1);
else
saver[j][k] = 1;
}
}
}
return saver.back().back();
}
};
3 标准解
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> memo(m+1, vector<int>(n+1, 0));
int numZeroes, numOnes;
for (auto &s : strs) {
numZeroes = 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--) {
memo[i][j] = max(memo[i][j], memo[i - numZeroes][j - numOnes] + 1);
}
}
}
return memo[m][n];
}
};