在計算機界中,我們總是追求用有限的資源獲取最大的收益。
現在,假設你分別支配着 m 個 0 和 n 個 1。另外,還有一個僅包含 0 和 1 字符串的數組。
你的任務是使用給定的 m 個 0 和 n 個 1 ,找到能拼出存在於數組中的字符串的最大數量。每個 0 和 1 至多被使用一次。
注意:
給定 0 和 1 的數量都不會超過 100。 給定字符串數組的長度不會超過 600。 示例 1:
輸入: Array = {“10”, “0001”, “111001”, “1”, “0”}, m = 5, n = 3 輸出: 4
解釋: 總共 4 個字符串可以通過 5 個 0 和 3 個 1 拼出,即 “10”,“0001”,“1”,“0” 。 示例 2:
輸入: Array = {“10”, “0”, “1”}, m = 1, n = 1 輸出: 2
解釋: 你可以拼出 “10”,但之後就沒有剩餘數字了。更好的選擇是拼出 “0” 和 “1” 。
public static int findMaxForm(String[] strs, int m, int n) {
if (strs.length == 0) {
return 0;
}
int dp[][] = new int[m + 1][n + 1];
//對每個字符串遍歷
for (int k = 0; k < strs.length; k++) {
int count0 = 0;
int count1 = 0;
//計算當前字符串需要花費的0和1的個數
for (int j = 0; j < strs[k].length(); j++) {
if (strs[k].charAt(j) == '0') {
count0++;
} else {
count1++;
}
}
//將當前位置擁有的0和1減去需要花費的後,剩餘的dp值+1就是當前的可能最大值
for (int i = m; i >= count0; i--) {
for (int j = n; j >= count1; j--) {
dp[i][j] = Math.max(dp[i][j], 1 + dp[i - count0][j - count1]);
}
}
}
return dp[m][n];
}
由於每個字符串只花費一次,因此是一個有限揹包問題,需要從後往前遍歷dp