Loading

【力扣】零和一(不是多重背包)

题目描述

image
image

分析

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

#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;
}
posted @ 2024-03-19 15:58  SaTsuki26681534  阅读(19)  评论(0)    收藏  举报