leetcode 474. Ones and Zeroes(背包问题)

In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.

For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s.

Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once.

Note:

  1. The given numbers of 0s and 1s will both not exceed 100
  2. The size of given string array won't exceed 600.

Example 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”

Example 2:

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".

背包问题,容量[m,n],价值为选择的字符串个数。

三维dp空间复杂度可以缩减到2维。有两种方式的dp,第二种dp能存下更多的信息

1.dp[j][k]代表总共可用[j,k]容量时的最大价值,第一种为dp[j][k]=max(dp[j][k],dp[j-c1][k-c2]+1);

2.dp[j][k]代表能刚好得到[j,k]容量时的最大价值(dp[m][n]可能为0);第二种为dp[i+c1][j+c2]=max(dp[i+c1][j+c2],dp[i][j]+1);

   (第二种dp[j][k]=max(dp[j][k],dp[j-c1][k-c2]+1)或者这样构造也行)

c1,c2为一个字符串0,1的个数。注意边界情况。

第一种dp。

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int len=strs.length;
        int[][] dp=new int[m+1][n+1];
        for(int i=0;i<len;i++){
            int c1=0,c2=0;
            for(int j=0;j<strs[i].length();j++){
                if(strs[i].charAt(j)=='0') c1++;
                else c2++;
            }
            for(int j=m;j>=0;j--){
                for(int k=n;k>=0;k--){
                    if(i==0){
                        if(j>=c1&&k>=c2){
                            dp[j][k]=1;
                        }    
                    }else{
                        dp[j][k]=dp[j][k];
                        if(j>=c1&&k>=c2){
                            dp[j][k]=Math.max(dp[j-c1][k-c2]+1,dp[j][k]);
                        }
                    }
                }
            }
        }
        return dp[m][n];
    }
}

第二种dp.

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        // dp[j+c1][k+c2]=dp[j][k]+1
        int len=strs.length;
        int[][] dp=new int[m+1][n+1];
        for(int i=0;i<len;i++){
            int c1=0,c2=0;
            for(int j=0;j<strs[i].length();j++){
                if(strs[i].charAt(j)=='0') c1++;
                else c2++;
            }
            for(int j=m;j>=0;j--){
                for(int k=n;k>=0;k--){
                    if(dp[j][k]==0&&!(j==0&&k==0)) continue;
                    if(j+c1<=m&&k+c2<=n){
                        dp[j+c1][k+c2]=Math.max(dp[j][k]+1,dp[j+c1][k+c2]);    
                    }
                }
            }
        }
        int max=0;
        for(int j=m;j>=0;j--){
            for(int k=n;k>=0;k--){
                max=Math.max(max,dp[j][k]);
            }
        }
        return max;
    }
}

猜你喜欢

转载自blog.csdn.net/yaoct/article/details/85250589