474. 一和零 - 力扣(LeetCode)
这一道题主要是把实际问题抽象为背包问题,对于每一个字符串的价值都是1,每一个字符串的体积由两部分组成,0和1的大小,所以判断时需要同时满足0和1的大小同时小于给定的01大小(背包容量)。
我们先求出每一个字符串的体积(0和1的个数),第一层循环即为遍历所有的字符串,内循环为双层循环,因为要同时满足两个条件,k为当前的字符串,i为背包0的容量,j为背包1的容量。可以推出递推公式为:
dp[k][i][j] = max( dp[k - 1][ i ][ j ] , dp[k - 1][ i - cnt[ k - 1][ 0 ] ][ j - cnt[ k - 1][ 1 ] +1 )
public class Main {public static void main(String[] args) {String[] strs = { "10", "0001", "111001", "1", "0" };int m = 5;// m个0int n = 3;// n个1int a = findMaxForm(strs, m, n);System.out.println(a);}public static int findMaxForm(String[] strs, int m, int n) {int len = strs.length;int[][] cnt = new int[len][2];for (int i = 0; i < len; i++) {String str = strs[i];int ZeroCount = 0;int OneCount = 0;for (char c : str.toCharArray()) {if (c == '0')ZeroCount++;elseOneCount++;}cnt[i][0] = ZeroCount;cnt[i][1] = OneCount;}int[][][] dp = new int[len + 1][m + 1][n + 1];for (int k = 1; k <= len; k++) {int zero = cnt[k - 1][0];int one = cnt[k - 1][1];for (int i = 0; i <= m; i++) {for (int j = 0; j <= n; j++) {// 不选int a = dp[k - 1][i][j];// 选int b = (i >= zero && j >= one) ? dp[k - 1][i - zero][j - one] + 1 : 0;dp[k][i][j] = Math.max(a, b);}}}return dp[len][m][n];}}