一、问题描述————————原题链接
给定一个字符串集合,如:{“10”, “0001”, “111001”, “1”, “0”},该字符串数组的元素只含有01,给定两个输入m = 5(有5个0), n = 3(有3个1),问,在不重复使用这5个0和3个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”
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[k1][k2],为k1个0,k2个1能够表示集合中最大元素个数。对于集合中的元素(假设该元素具有i个0,k个1)有2种选择:
①要么将该元素加入,dp[k1][k2]=dp[k1-i][k2-1];
②要么不加入该元素,dp[k1][k2]保持不变。
三、源代码
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
int dp[m + 1][n + 1];
for(int i = 0 ; i <= m; i ++)
for(int j = 0; j <= n; j ++)
dp[i][j] = 0;
int one_num, zero_num;
for(int i = 0; i < strs.size(); i ++)
{
string cur = strs[i];
one_num = 0;
zero_num = 0;
for(int j = 0; j < cur.length(); j ++)
{
if(cur[j] == '0')
zero_num ++;
else
one_num ++;
}
for(int k1 = m; k1 >= zero_num ; k1 --)
{
for(int k2 = n; k2 >= one_num; k2 --)
{
int temp = dp[k1 - zero_num][k2 - one_num] + 1;
if(dp[k1][k2] < temp)
dp[k1][k2] = temp;
}
}
}
return dp[m][n];
}
};