1. 程式人生 > >leetcode 474. Ones and Zeroes(揹包問題)

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;
    }
}