[LeetCode] 474. 一和零
- 一和零
把总共的 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];
}
}