题干:
代码 :
class Solution {
public:
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0));
dp[0][0] = 0;
for(string i : strs){
int oneNum = 0;
int zeroNum = 0;
for(char c : i){
if(c == '1') oneNum++;
if(c == '0') zeroNum++;
}
for(int j = m; j >= zeroNum; j--){
for(int k = n; k >= oneNum; k--){
dp[j][k] = max(dp[j][k], dp[j - zeroNum][k - oneNum] + 1);
}
}
}
return dp[m][n];
}
};
思路:将m, n视为背包的属性,故问题转化为了将m,n容量的背包转满最多能装多少个,而每样物品只能装一次,问题转化成了01背包问题。
定义dp数组:容量为m,n的背包所能装下的最大数量,故定为二维数组。
递推公式:dp[m][n] = max(dp[m][n], dp[m-zeroNum][n-oneNum] + 1),‘0’、‘1’数目是物品的重量,1(个)是物品的价值。实际上是三维数组,只不过背包有两个属性而已,用类似是一维数组方法写。
初始化:dp[0][0] = 0,其他都可以用这个推出来。
遍历顺序:先物品后背包,背包要倒序遍历。遍历物品时同时统计‘0’、‘1’数量。