1. 程式人生 > >[LeetCode] 474. Ones and Zeroes

[LeetCode] 474. Ones and Zeroes

題:https://leetcode.com/problems/ones-and-zeroes/description/

題目

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:
The given numbers of 0s and 1s will both not exceed 100
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".

題目大意

有一組 字串 string,給定 m個‘1’,與n個‘0’。選擇字串組,使用的‘1’與‘0’小於 m與n。
求最多有多少個 字串。

思路

這是一個多維費用的 0-1 揹包問題,有兩個揹包大小,0 的數量和 1 的數量。

狀態 dp[i][j][k]:遍歷到 第 i個 物品(字串),使用 j個’0’ 、 k個’1’時,能包含的最多 物品數(字串數)

狀態轉移方程:

 if(j-num0>=0 && k-num1>=0)
     dp[i][j][k] = Math.max(dp[i-1][j][k],dp[i-1][j-num0][k-num1]+1);
 else
     dp[i][j][k] = dp[i-1][j][k];

初始化
dp[0][j][k] = 0;

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

由於 dp[i][j][k] 只用到了 dp[i-1],所以 可以用 二維陣列表示 dp。

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