题干:

代码 :
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’数量。



















