一般的な学習
実際、多くの人は、ある種の暴力的な解決策に基づいてアルゴリズムの問題を考え、列挙しようとします。列挙が成功した場合、問題は完了する可能性があります。ただし、列挙が失敗した場合、途方に暮れます。テストシステムは、問題の実行時間が超過していることを通知します。スコープが制限されている場合、彼はまだかなりハゲです。
実際、以前は動的計画法を使って問題を解決していましたが、このアルゴリズムは英語の単語に似ていることがわかりました。長期間使用しないと忘れてしまいます。動的計画法の解決策をもう一度試したいと思ったとき、ナップサック問題の4つの単語を覚えている以外に頭が真っ白だったので、動的計画法のナップサック問題について学ぶために偉大なる神のブログに行きました。この古典的なアルゴリズムを学び終えるたびに、私は自分自身に新しい感覚を与えることができるので、私はLikouゾーンに行って、そのような質問をさらにいくつかブラッシングして練習することにしました。
474.ワンアンドゼロ(Li Kou)
给你一个二进制字符串数组 strs 和两个整数 m 和 n 。
请你找出并返回 strs 的最大子集的大小,该子集中 最多 有 m 个 0 和 n 个 1 。
如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。
示例 1:
输入:strs = ["10", "0001", "111001", "1", "0"], m = 5, n = 3
输出:4
解释:最多有 5 个 0 和 3 个 1 的最大子集是 {
"10","0001","1","0"} ,因此答案是 4 。
其他满足题意但较小的子集包括 {
"0001","1"} 和 {
"10","1","0"} 。{
"111001"} 不满足题意,因为它含 4 个 1 ,大于 n 的值 3 。
示例 2:
输入:strs = ["10", "0", "1"], m = 1, n = 1
输出:2
解释:最大的子集是 {
"0", "1"} ,所以答案是 2 。
提示:
1 <= strs.length <= 600
1 <= strs[i].length <= 100
strs[i] 仅由 '0' 和 '1' 组成
1 <= m, n <= 100
熱意に溢れて、理解しているアルゴリズムのルーチンを試して解決しようと思っていますが、この質問は本当に頭を悩ませました。バックパックの問題が教えてくれるのは、バックパックのボリュームの変数を使用して選択肢を制限する方法です。最大の価値、この質問は2つの制約を与えました、えーと...実際、問題の間にはまだ共通点があると慎重に考えてください。バックパック問題は表面に1つの制限要因しかありませんが、動的に検討するときに別の要因を追加しました。選択できるアイテム数の制約。この質問には2つの制限がありますが、各文字列は1回しか使用できないため(つまり、限られたバックパック)、dp(i、j)を更新するときは、iとjの両方を列挙する必要があります。最大から最小へ。このように理解されるべき理由については、ナップサック問題の逆選択に相当します。dp(i、j)を使用して、i0sとj1sを使用してスペルアウトできる文字列の最大数を表すと、状態遷移方程式は次のようになります。
dp[i][j] = Math.max(1+dp[i-arr[0]][j-arr[1]], dp[i][j]);
ここで、kはk番目の文字列を表し、arr [0]とarr [1]は文字列内の0と1の数を表します。
public static int findMaxForm(String[] strs, int m, int n) {
int[][] dp = new int[m+1][n+1];
for(int k = 0;k < strs.length;k++) {
int[] arr = intcount(strs[k]);
for(int i = m;i >= arr[0];i--) {
for(int j = n;j >= arr[1];j--) {
dp[i][j] = Math.max(1+dp[i-arr[0]][j-arr[1]], dp[i][j]);
}
}
}
for(int i = 0;i <= m;i++) {
for(int j = 0;j <= n;j++) {
System.out.print(dp[i][j]+" ");
}
System.out.println();
}
return 0;
}
public static int[] intcount(String str) {
int[] arr = new int[2];
for(int i = 0;i < str.length();i++) {
if(str.charAt(i) == '0')
arr[0]++;
if(str.charAt(i) == '1')
arr[1]++;
}
return arr;
}