【力扣】零和一(不是多重背包)
题目描述


分析
其实分析起来并不陌生,找到这个集合的子集,并且是这个子集在0和1的个数不超限的前提下长度最大(含的字符串个数最多),但是新奇之处就在于这里有两个指标:0的个数和1的个数。
但是这题并不是多重背包,因为多重背包的情景是背包中有多重不同的物体,而这里背包里的物体只有一种,即01字符串,只是背包的容量是由0和1的数量这两个维度的指标决定的,所以这道题仍然是一般的01背包题。

代码如下:
#include<bits/stdc++.h>
using namespace std;
int numOf1(string s){
int num = 0;
for(int i = 0; i < s.size(); i++){
if(s[i] == '1'){
num++;
}
}
return num;
}
int numOf0(string s){
return s.size() - numOf1(s);
}
int findMaxForm(vector<string>& strs, int m, int n) {
vector<vector<int> > dp(m+1, vector<int>(n+1,0));
//dp数组代表的是最多有m个0和n个1的子集的最大长度
for(int i = 0; i < strs.size(); i++){
for(int j = m; j >= numOf0(strs[i]); j--){
for(int k = n; k >= numOf1(strs[i]); k--){
dp[j][k] = max(dp[j][k], dp[j - numOf0(strs[i])][k - numOf1(strs[i])] + 1);
}
}
}
for(int i = 0 ; i < m+1; i++){
for(int j = 0; j < n+1; j++){
cout<<dp[i][j]<<" ";
}
cout<<endl;
}
return dp[m][n];
}
int main(){
int n;
cin>>n;
vector<string> strs;
string s;
for(int i = 0; i < n; i++){
cin>>s;
strs.push_back(s);
}
int M,N;
cin >>M>>N;
cout<<findMaxForm(strs, M,N);
return 0;
}

浙公网安备 33010602011771号