LeetCode 474 Ones and Zeroes 题解

题意简述:有若干个由0和1组成的字符串,现在限定使用m个0和n个1,每个0和1至多使用1次,问最多能组成多少个给定的字符串。
输入:字符串的vector,m和n的值
输出:能组成的字符串的数目
示例:给出m=5,n=3。字符串有{“10”, “0001”, “111001”, “1”, “0”},最多可以组成4个字符串:“10,”0001”,”1”,”0”。


题解:
如果把提供的0和1看作容量分别为m和n的背包,把字符串的0和1看作对应需要的容量(例如字符串0001需要3个容量0和1个容量1),那么这个问题就可以看作二维的01背包问题。
跟一维的01背包的空间优化相同,二维的01背包可以只使用二维数组存放中间结果。考虑对于第i个字符串,0容量为j,1容量为k的情况下最多组成的字符串数,其状态转移方程如下,其中z[i]表示第i个字符串需要的0容量,o[i]表示第i个字符串需要的1容量。

dp(j,k)=max(dp(j,k),dp(jz[i],ko[i]+1) j=m,m1,...,z[i],k=n,n1,...,o[i]

算法的时间复杂度是 O(n3) ,空间复杂度是 O(n2)

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        if(strs.size() == 0) return 0;

        vector<int> ones,zeros;
        for(int i = 0;i < strs.size();i++) {
            bitset<200> temp(strs[i]);
            ones.push_back(temp.count());
            zeros.push_back(strs[i].size()-temp.count());
        }

        vector<vector<int>> dp;
        for(int i = 0;i <= m;i++) {
            vector<int> temp(n+1,0);
            dp.push_back(temp);
        }

        for(int i = 0;i < strs.size();i++) {
            for(int j = m;j >= zeros[i];j--) {
                for(int k = n;k >= ones[i];k--) {
                    dp[j][k] = max(dp[j][k], dp[j-zeros[i]][k-ones[i]]+1);
                }
            }
        }

        return dp[m][n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值