题目描述:
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".
给定一个字符串数组和固定个数的“0”和“1”,求问用这些“0”和“1”可以组成数组中的那些字符串,也就是这些字符串的“0”和“1”的总数不超过给定的数目。采用动态规划,用dp[i][j]表示用i个“0”和j个“1”可以构造的字符串数目,那么遍历每一个字符串,确定它包含的“0”和"1"的数目,对于dp[i][j]有递推关系dp[i][j]=max(dp[i][j],dp[i-zeros][j-ones]+1)。需要注意的是每次i都是从m开始遍历,j都是从n开始遍历,目的就是为了让上一轮的dp的结果来更新当前的dp数组,否则在一轮循环中如果strs[k]已经用来更新了dp[a][b],然后又可能用更新后的dp[a][b]来更新dp[c][d],导致strs[k]使用了两次,这明显是错误的,而从大往小遍历就必然用到的是前一轮对应的数组值。
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
for(int k=0;k<strs.size();k++)
{
int zeros=get_count(strs[k]).first;
int ones=get_count(strs[k]).second;
for(int i=m;i>=zeros;i--)
for(int j=n;j>=ones;j--)
dp[i][j]=max(dp[i][j],dp[i-zeros][j-ones]+1);
}
return dp[m][n];
}
pair<int,int> get_count(string s)
{
int a=0;
int b=0;
for(int i=0;i<s.size();i++)
{
if(s[i]=='0') a++;
else b++;
}
return pair<int,int>(a,b);
}
};