leetcode 474 一和零
一、题目描述

二、解题思路
解法一:深度优先搜索+剪枝(超时)
本题实际上与0/1背包问题类似,即子集问题的变种,可以采用深度优先搜索+剪枝来解决这个问题,对于每一个字符串,只有选择和不选择两种决策。
解法二:动态规划
dp[i][j]表示m=i,n=j时,最大的子集数,对于每一个字符串,只有选择与不选择两种情况,所以dp[i][j]=max(dp[i][j],dp[i-zeros][j-ones]),这就是状态转移方程,依此来写就可以了。
三、代码实现
解法一:深度优先搜索+剪枝(超时)
class Solution {int length;vector<vector<int>> count;
public:int findMaxForm(vector<string>& strs, int m, int n) {//初始化全局变量length=0;//初始化count数组,记录每个字符串中'0'和'1'的个数count.resize(strs.size(),vector<int>(2,0));for(int i=0;i!=strs.size();i++){for(auto ch:strs[i]){if(ch=='0') count[i][0]++;else if(ch=='1') count[i][1]++;}}dfs(strs,0,m,n,0);return length;}void dfs(vector<string>& strs,int start,int m,int n,int currentLength){//递归出口if(start==strs.size()){length=max(length,currentLength);return ;}//当前字符串的'1'和'0'的数量int zeros=count[start][0];int ones=count[start][1];//选if(m>=zeros&&n>=ones)dfs(strs,start+1,m-zeros,n-ones,currentLength+1);//不选dfs(strs,start+1,m,n,currentLength);}
};
解法二:动态规划(可通过)
class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {//动态规划//dp[i][j]表示m=i,n=j时,最大子集的长度vector<vector<int>> dp(m+1,vector<int>(n+1,0));for(auto str:strs){int zeros=count(str.begin(),str.end(),'0');int ones=(int)str.size()-zeros;//填写dp数组for(int i=m;i>=zeros;i--)for(int j=n;j>=ones;j--)dp[i][j]=max(dp[i][j],dp[i-zeros][j-ones]+1);}return dp[m][n];}
};
