[LeetCode] 474. 一和零

  1. 一和零

把总共的 0 和 1 的个数视为背包的容量,每一个字符串视为装进背包的物品。这道题就可以使用 0-1 背包问题的思路完成,这里的目标值是能放进背包的字符串的数量。

动态规划的思路是:物品一个一个尝试,容量一点一点尝试,每个物品分类讨论的标准是:选与不选。

定义状态:尝试题目问啥,就把啥定义成状态。dp[i][j][k] 表示输入字符串在子区间 [0, i] 能够使用 j 个 0 和 k 个 1 的字符串的最大数量。

状态转移方程:

dp[i][j][k]=\left{
\begin{aligned}
dp[i-1][j][k],
dp[i-1][j-count0][k-count1]
\end{aligned}
\right.

初始化:为了避免分类讨论,通常多设置一行。这里可以认为,第 00 个字符串是空串。第 00 行默认初始化为 00。 输出:输出是最后一个状态,即:dp[i][j][k]

class Solution {
    public int findMaxForm(String[] strs, int m, int n) {
        int len = strs.length;
        int[][][] f= new int[len+1][m+1][n+1];
        for (int i=1;i<=len;i++) {
            String s = strs[i-1];
            int p = 0;
            int q = 0;
            for (int k = 0;k<s.length();k++) {
                if (s.charAt(k) == '0') {
                    p++;
                } else {
                    q++;
                }
            }

            for (int a=0;a<=m;a++) {
                for (int b=0;b<=n;b++) {
                    f[i][a][b] = f[i-1][a][b];
                    if (a>=p&&b>=q) {
                        f[i][a][b] = Math.max(f[i-1][a][b], f[i-1][a-p][b-q]+1);
                    }
                }
            }
        }

        return f[len][m][n];
    }
}
posted @ 2021-06-06 12:56  ACBingo  阅读(36)  评论(0编辑  收藏  举报