题目
思路
我们观察上图,画出树状图之后对于我们解题可能会清楚一点,从这张图我们能直观的看出来,对于m个0和n个1,它所能拼成最大的字符串数量应该就是各个子树所能拼成最大的字符串数量加上1。
首先我们要明确的是dp表所表示的含义,这样才能更好的推出动态规划方程
一开始我设置dp[i][j]表示i个0和j个1所能表示的最大字符串数量,但是动态规划方程却短路了,没有能推出来。分析自己的思路,首先确定的是dp表所表示的含义是正确的,那么存在的问题就是动态规划方程没有推出来。
我们可以再进一步优化我们的思想,dp[i][j]表示:对于遍历到的数组字符串范围内,i个0和j个1所能拼出存在于数组中的字符串的最大数量,则动态规划方程为:dp[i][j]=max(dp[i][j],dp[i-one][j-zero]),该动态规划方程表示,对于遍历到的数组字符串范围内,i个0和j个1所能拼出存在于数组中的字符串的最大数量,那么对于i个0和j个1所能拼出存在于数组中的字符串的最大数量,一种情况就是包含了当前遍历到的那么字符串,另一种情况就是不包含当前遍历到的那个字符串
那我们的思路应该是:每次遍历一个数组字符串,我们就求出对于当前给定的0和1的个数所能拼成的最大字符串数量,相关代码如下:
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
for (auto str:strs) {
int one = 0, zero = 0;
for (auto ch : str) {
if (ch == '1')one++;
else zero++;
}
for (int i = m; i >= zero; i--) {
for (int j = n; j >= one; j--) {
dp[i][j] = max(dp[i][j], dp[i - zero][j - one]+1);
}
}
}
return dp[m][n];
}
};