Ones and Zeroes 一和零

在计算机界中,我们总是追求用有限的资源获取最大的收益。

现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。

你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每个 0 和 1 至多被使用一次

注意:

  1. 给定 0 和 1 的数量都不会超过 100
  2. 给定字符串数组的长度不会超过 600

示例 1:

输入: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
输出: 4

解释: 总共 4 个字符串可以通过 5 个 0 和 3 个 1 拼出,即 "10","0001","1","0" 。

示例 2:

输入: Array = {"10", "0", "1"}, m = 1, n = 1
输出: 2

解释: 你可以拼出 "10",但之后就没有剩余数字了。更好的选择是拼出 "0" 和 "1" 。

思路:这道题是背包问题中01背包的变形版,有点不同的是我们的容量变成了m和n,其中m表示剩余0的个数,n表示剩余1的个数,我们把唯独约减到二维,递推公式为:

dp[p][q] = max(dp[p][q], dp[p - result[0]][q - result[1]]+1);

其中dp为长度为m*n的二维数组,其中dp[m][n]表示还剩下m个0和n个1时的最优解,这里多说一句,不进行空间优化的递推公式如下:

dp[i][p][q] = max(dp[i-1][p][q], dp[i-1][p - result[0]][q - result[1]]+1);

其中dp[i][p][q]表示从第一个元素到第i个元素为止,背包容量还剩p个0和q个1时的最优解,这里每个商品的价值为1,所以我们的目标是在所有的商品中选择某些商品使得在不超出背包容量p和q的情况下使得价值最大。这是三维数组,我们把它优化成二维数组,如上个公式所示。

参考代码如下:

class Solution {
public:
vector<int> count(string &s) {
	if (s.size() == 0) {
		return { 0,0 };
	}
	int sum_zero = 0;
	int sum_one = 0;
	for (int i = 0; i < s.size(); i++) {
		if (s[i] == '0') {
			sum_zero++;
		}
		else {
			sum_one++;
		}
	}
	return { sum_zero,sum_one };
}
int findMaxForm(vector<string>& strs, int m, int n) {
	int len = strs.size();
	int res = 0;
	if (len == 0) {
		return 0;
	}
	int **dp = new int *[m + 1];
	for (int i = 0; i < m + 1; i++) {
		dp[i] = new int[n + 1];
	}
	for (int i = 0; i < m + 1; i++) {
		for (int j = 0; j < n + 1; j++) {
			dp[i][j] = 0;
		}
	}
	for (int i = 0; i < len; i++) {
		for (int p = m; p >= 0; p--) {
			for (int q = n; q >= 0; q--) {
				vector<int> result = count(strs[i]);
				if (p >= result[0] && q >= result[1]) {
					dp[p][q] = max(dp[p][q], dp[p - result[0]][q - result[1]]+1);
				}
			}
		}
	}
	res = dp[m][n];
	for (int i = 0; i < m + 1; i++) {
		delete[] dp[i];
	}
	delete[] dp;
	return res;
}
};




在计算机界中,我们总是追求用有限的资源获取最大的收益。

现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。

你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每个 0 和 1 至多被使用一次

注意:

  1. 给定 0 和 1 的数量都不会超过 100
  2. 给定字符串数组的长度不会超过 600

示例 1:

输入: Array = {"10", "0001", "111001", "1", "0"}, m = 5, n = 3
输出: 4

解释: 总共 4 个字符串可以通过 5 个 0 和 3 个 1 拼出,即 "10","0001","1","0" 。

示例 2:

输入: Array = {"10", "0", "1"}, m = 1, n = 1
输出: 2

解释: 你可以拼出 "10",但之后就没有剩余数字了。更好的选择是拼出 "0" 和 "1" 。

猜你喜欢

转载自blog.csdn.net/qq_26410101/article/details/80848037