dfs超时。考虑dp,三维dp,其实从本质来说还是01背包,只是要考虑的不只只是物品的重量,还有物品的大小(假设这样打比方),就是放进一个物品时,要考虑它的0和1。所以就是dp[i][j][k]表示在前i个字符串中,用j个0和k个1最多可以组成几个字符串。
每一轮计算当前字符串的0和1的个数。
状态转移:看看当前字符串取或者不取,如果取了没超的话就取dp[i][j][k] = dp[i-1][j-one][k-zero]+1
如果不取就dp[i][j][k] = dp[i-1][j][k]
可以考虑状压,详情见代码。
class Solution {
public:
// void dfs(vector<string>& strs,int m, int n,int tmpZero,int tmpOne, int index,int num){
// //计算加上这个数是否正常,防止一开始进来第一个就不满足了,在main中也要for循环对每次数字开头
// int one = 0, zero = 0;
// for(char c:strs[index]){
// if(c == '0') zero++;
// if(c == '1') one++;
// }
// if(tmpOne + one >n || tmpZero + zero > m) return;
// res = max(res,num);
// tmpOne += one;
// tmpZero += zero;
// for(int i = index+1; i < strs.size(); ++i){
// dfs(strs,m,n,tmpZero,tmpOne,i,num+1);
// }
// }
int findMaxForm(vector<string>& strs, int m, int n) {
//尽可能把0和1用完才能组成更多的数字
//dfs爆搜,每次加入一个元素就计算0和1的总量是否超了,如果超了就返回如果没超就看看能否更新res
// for(int i = 0; i < strs.size(); ++i){
// dfs(strs,m,n,0,0,i,1);
// }
// return res;
//也是01背包,看当前数字取或者不取,dp[i][j][k]表示在前i个字符串中,用j个0和k个1最多可以组成几个字符串
//状态转移:看看当前字符串取或者不取,如果取了没超的话就取dp[i][j][k] = dp[i-1][j-one][k-zero]+1
//如果不取就dp[i][j][k] = dp[i-1][j][k]
//vector<vector<vector<int>>> dp(strs.size()+1,vector<vector<int>>(m+1,vector<int>(n+1,0)));
//basecase:当取0个0和0个1的时候最多组成0个字符串,所以在一开始全部赋为0即可
// for(int i = 1; i <= strs.size(); ++i){
// int one = 0;
// int zero = 0;
// for(char c : strs[i-1]){
// if(c == '0') zero++;
// if(c == '1') one++;
// }
// //接下来就是考虑要不要取当前数字
// for(int j = 0; j <= m; ++j){
// for(int k = 0; k <= n; ++k){
// if(zero <= j && one <= k){
// dp[i][j][k] = dp[i-1][j-zero][k-one]+1;
// }
// dp[i][j][k] = max(dp[i][j][k],dp[i-1][j][k]);
// }
// }
// }
// return dp[strs.size()][m][n];
//只和前一维的结果有关系
vector<vector<int>> dp(m+1,vector<int>(n+1,0));
//basecase就是对于取0个0和0个1我们只有0种方法
//这次内部循环要反向遍历了,因为要取左上的,不能从前往后更新,这样会把左上的给更新掉
for(int i = 0; i < strs.size(); ++i){
int zero = 0;
int one = 0;
for(char c : strs[i]){
if(c == '0') zero++;
if(c == '1') one++;
}
for(int j = m; j >= zero; --j){
for(int k = n; k >= one; --k){
dp[j][k] = max(dp[j][k],dp[j-zero][k-one]+1);
}
}
}
return dp[m][n];
}
// private:
// int res = 0;
};