/**
* 474. 一和零
* @author wsq
* @date 2020/10/11
计算机界中,我们总是追求用有限的资源获取最大的收益。
现在,假设你分别支配着 m 个 0 和 n 个 1。另外,还有一个仅包含 0 和 1 字符串的数组。
你的任务是使用给定的 m 个 0 和 n 个 1 ,找到能拼出存在于数组中的字符串的最大数量。每个 0 和 1 至多被使用一次。
示例 1:
输入: strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
输出: 4
解释: 总共 4 个字符串可以通过 5 个 0 和 3 个 1 拼出,即 "10","0001","1","0" 。
示例 2:
输入: strs = ["10", "0", "1"], m = 1, n = 1
输出: 2
解释: 你可以拼出 "10",但之后就没有剩余数字了。更好的选择是拼出 "0" 和 "1" 。
链接:https://leetcode-cn.com/problems/ones-and-zeroes
*/
package com.wsq.dp;
public class FindMaxForm {
/**
* 类似背包问题,不过这里是两个容器,按照原始的背包问题去解决的话
* 这里我们建立动态规划矩阵应该是个3维的,但是考虑到后一种情况的只和前一种情况的相关,
* 因此,这里将表示物品的维度给省略了
* @param strs
* @param m
* @param n
* @return
*/
public int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m + 1][n + 1];
for(String str: strs) {
int[] count = countZeroesAndOnes(str);
for(int i = m; i >= count[0]; i--) {
for(int j = n; j > count[1]; j--) {
dp[i][j] = Math.max(1 + dp[i-count[0]][j-count[1]], dp[i][j]);
}
}
}
return dp[m][n];
}
public int[] countZeroesAndOnes(String str) {
int[] ans = new int[2];
for(char c:str.toCharArray()) {
ans[c-'0']++;
}
return ans;
}
public static void main(String[] args) {
String[] strs = {"10", "0001", "111001", "1", "0"};
int m = 3;
int n = 2;
FindMaxForm fm = new FindMaxForm();
int ans = fm.findMaxForm(strs, m, n);
System.out.println(ans);
}
}
474. 一和零(动态规划)
最新推荐文章于 2022-10-20 20:49:50 发布