leetcode 474. 一和零

2023.8.15

class Solution {
public:
    int findMaxForm(vector& strs, int m, int n) {
        vector> dp(m+1, vector(n+1,0));
        //遍历物品
        for(string str : strs)
        {
            int num_0 = 0;
            int num_1 = 0;
            for(char c : str)
            {
                if(c == '0') num_0++;
                else num_1++;
            }
            //遍历二维背包
            for(int i=m; i>=num_0; i--)
            {
                for(int j=n; j>=num_1; j--)
                {
                    dp[i][j] = max(dp[i][j] , 1 + dp[i-num_0][j-num_1]);
                }
            }
        }
        return dp[m][n];
    }
};

        依旧是0-1背包问题的应用。 本题不易看出是0-1背包问题,因为本题的背包有两个:m和n。因此需要定义一个二维的dp数组。数组strs中的一个个字符串就是我们的物品。dp[i][j]的含义为:两背包大小分别为i和j时,所能装的最多物品。

        在遍历物品(即字符串数组)时,需要先将每个物品(字符串)的0和1个数统计起来。然后分别遍历两个背包。每次更新dp数组时,可以选择取当前物品或者不取当前物品。 不取当前物品:dp[i][j] = dp[i][j];  取当前物品:dp[i][j] = 1 + dp[i-num_0][j-num_1];   择其最大的。

        代码如下:

class Solution {
public:
    int findMaxForm(vector& strs, int m, int n) {
        vector> dp(m+1, vector(n+1,0));
        //遍历物品
        for(string str : strs)
        {
            int num_0 = 0;
            int num_1 = 0;
            for(char c : str)
            {
                if(c == '0') num_0++;
                else num_1++;
            }
            //遍历二维背包
            for(int i=m; i>=num_0; i--)
            {
                for(int j=n; j>=num_1; j--)
                {
                    dp[i][j] = max(dp[i][j] , 1 + dp[i-num_0][j-num_1]);
                }
            }
        }
        return dp[m][n];
    }
};

        至此,做了四道0-1背包应用的相关题目,总结一下:

分割等和子集:是求:给定背包容量,能否装满这个背包。

最后一块石头的重量II:是求:给定背包容量,尽可能装,最多能装多少。

目标和:是求:给定背包容量,装满背包有多少种方法。

本题:是求:给定背包容量,装满背包最多有多少个物品。

你可能感兴趣的:(leetcode专栏,leetcode,算法,数据结构,c++)