背包问题

1. ones and zeros

1.1 递归以及记忆化搜索

 public class Solution {
    int[] ones;
    int[] zeros;
    int[][][] memo;
     public int findMaxForm(String[] strs, int m, int n) {
            if (strs == null || strs.length == 0) {
                return 0;
            } 
            this.ones = new int[strs.length];
            this.zeros = new int[strs.length];
            getArrFromStr(strs);
            memo = new int[m+1][n+1][strs.length];
            for (int i = 0; i <= m; i++){ 
                for (int j = 0; j <= n; j++) {
                    for (int k = 0; k= strs.length || zv < 0 || ov < 0) { 
                return 0;
            } 
            if (memo[zv][ov][index] != -1) {
                return memo[zv][ov][index];
            }
            
            int res = helper(strs,   zv,  ov, index + 1);
            if (zv >= zeros[index]  && ov >= ones[index] ) { 
                res = Math.max(res, 1 + helper(strs,   zv - zeros[index],  ov - ones[index], index + 1));
            }
            memo[zv][ov][index] = res;
            return res;
        } 
        
        private void getArrFromStr (String[] strs) {
            for (int i = 0; i < strs.length; i++){
                String str = strs[i];
                char[] charArr  =  str.toCharArray();
                for (char c : charArr) {
                    if (c=='0') {
                        this.zeros[i]++;
                    }else {
                        this.ones[i]++;
                    }
                }
            }
        } 
} 

1.2 动态规划

dp[i][j]表示有i个0和j个1时能组成的最多字符串的个数,而对于当前遍历到的字符串,我们统计出其中0和1的个数为zeros和ones,然后dp[i - zeros][j - ones]表示当前的i和j减去zeros和ones之前能拼成字符串的个数,那么加上当前的zeros和ones就是当前dp[i][j]可以达到的个数,我们跟其原有数值对比取较大值即可,所以递推式如下:

dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1);

public class Solution {
    int[] ones;
    int[] zeros;
    int[][] dp;
     public int findMaxForm(String[] strs, int m, int n) {
            if (strs == null || strs.length == 0) {
                return 0;
            } 
            this.ones = new int[strs.length];
            this.zeros = new int[strs.length];
            getArrFromStr(strs);
            dp  = new int[m + 1][n + 1];
            
            for (int i = 0; i < strs.length; i++) {
                for (int z = m; z >= zeros[i]; z--){
                    for (int o = n; o >= ones[i]; o--){
                        dp[z][o] = Math.max(dp[z][o], 1 + dp[z - zeros[i]][o - ones[i]]); 
                    }
                }     
            }
            
            return dp[m][n];
        }
        
        
         
        
        private void getArrFromStr (String[] strs) {
            for (int i = 0; i < strs.length; i++){
                String str = strs[i];
                char[] charArr  =  str.toCharArray();
                for (char c : charArr) {
                    if (c=='0') {
                        this.zeros[i]++;
                    }else {
                        this.ones[i]++;
                    }
                }
            }
        } 
}

你可能感兴趣的:(背包问题)