2023.8.15
class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {vector<vector<int>> dp(m+1, vector<int>(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<string>& strs, int m, int n) {vector<vector<int>> dp(m+1, vector<int>(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:是求:给定背包容量,尽可能装,最多能装多少。
目标和:是求:给定背包容量,装满背包有多少种方法。
本题:是求:给定背包容量,装满背包最多有多少个物品。