力扣 474. 一和零

题目来源:https://leetcode.cn/problems/ones-and-zeroes/description/

力扣 474. 一和零_第1张图片

力扣 474. 一和零_第2张图片 

 C++题解:本题其实是01背包问题!只不过这个背包有两个维度,一个是m 一个是n,而不同长度的字符串就是不同大小的待装物品。动规五部曲:

  1. 确定dp数组(dp table)以及下标的含义。dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]
  2. 确定递推公式。dp[i][j] 可以由前一个strs里的字符串推导出来,strs里的字符串有zeroNum个0,oneNum个1。dp[i][j] 就可以是 dp[i - zeroNum][j - oneNum] + 1。然后我们在遍历的过程中,取dp[i][j]的最大值。所以递推公式:dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
  3. dp数组如何初始化。因为物品价值不会是负数,初始为0,保证递推的时候dp[i][j]不会被初始值覆盖。
  4. 确定遍历顺序。01背包外层for循环遍历物品,内层for循环遍历背包容量且从后向前遍历!本题也是,物品就是strs里的字符串,背包容量就是题目描述中的m和n。
  5. 举例推导dp数组。
class Solution {
public:
    int findMaxForm(vector& strs, int m, int n) {
        int len = strs.size();
        // strs每个元素的01个数情况
        vector zs(len, 0), os(len, 0);
        for(int i = 0; i < len; i++){
            int chang = strs[i].size();
            for(int j = 0; j < chang; j++){
                if(strs[i][j] == '0') zs[i]++;
                else os[i]++;
            }
        }

        // 二维动态数组,从后往前遍历
        // dp[i][j]:最多有i个0和j个1的strs的最大子集的大小为dp[i][j]。
        vector> dp(m+1, vector(n+1, 0));
        for(int i = 0; i < len; i++) {
            for(int j = m; j >= zs[i]; j--) {
                for(int k = n; k >= os[i]; k--) {
                    dp[j][k] = max(dp[j][k], dp[j-zs[i]][k-os[i]] + 1);
                }
            }
        }
        return dp[m][n];
    }
};


代码随想录代码:

class Solution {
public:
    int findMaxForm(vector& strs, int m, int n) {
        vector> dp(m + 1, vector (n + 1, 0)); // 默认初始化0
        for (string str : strs) { // 遍历物品
            int oneNum = 0, zeroNum = 0;
            for (char c : str) {
                if (c == '0') zeroNum++;
                else oneNum++;
            }
            for (int i = m; i >= zeroNum; i--) { // 遍历背包容量且从后向前遍历!
                for (int j = n; j >= oneNum; j--) {
                    dp[i][j] = max(dp[i][j], dp[i - zeroNum][j - oneNum] + 1);
                }
            }
        }
        return dp[m][n];
    }
};

你可能感兴趣的:(开始C++吧,leetcode,算法,c++,动态规划,背包问题)