动态规划通用解法

简述

本文主要介绍动态规划问题的解法模板,以leetcode474为例,该问题为01背包问题的变体。

题目描述

给定字符串数组,数组中的元素由“0”或者“1”构成,若给定子字符串数组中存在“0”的个数最多为m、存在“1”的个数最多为n,返回满足该条件的子字符串数组的最大长度。
原字符串数组为[“10”,“0001”,“111001”,“1”,“0”],[“1”]、[“1”,“0”]…等都为其子字符串数组。

1、确定数组下标及值含义

value = dp[i][j];其中 0 <= i <= m、 0 <= j <= n;
该数组下标的含义:
i代表“0”存在的数量,j代表“1”存在的数量。
value的含义:
代表子字符串数组满足“0”的数量不多于i,“1”的数量不多于j的条件时,该数组的最大长度。

2、确定动态转移方程

根据数组下标及值含义,我们可以确定动态转移方程为:
dp[i][j] = max(dp[i][j], dp[i - numberOfZero][j - numberOfOne] + 1)
注:其中numberOfZero代表从字符串数组中取出元素包含“0”的数量,numberOfOne代表取出元素包含"1"的数量。
该动态转移方程的含义:求满足条件的dp[i][j]的最大值。

3、dp数组初始化

dp[0][0] = 0 代表下标i,j均为零时,该字符串数组的长度。
其余元素均初始化零,因为所有的dp[i][j] >= 0,初始化为0不影响转移方程的递推。

4、确定遍历的顺序

为防止物品被重复放入,物品被放在最外层遍历,而i和j放在里层遍历。

实现代码如下

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> vec;
        for (int i = 0; i < strs.size(); ++i) {
            vector<int> vecRes = calNum(strs[i]);
            vec.push_back(vecRes);
        }
        vector<int> vecN(n + 1, 0);
        vector<vector<int>> vecMN(m + 1, vecN);
        for (int k = 0; k < vec.size(); ++k) {
            for (int i = m; m >= vec[k][0]; --i)
                for (int j = n; n >= vec[k][1]; --j) {
                    vecMN[i][j] = max(vecMN[i][j], vecMN[i - vec[k][0]][j - vec[k][1]] + 1);
                }
        }
        return vecMN[m][n];
    }

    vector<int> calNum(string str) {
        int m = 0;
        int n = 0;
        for (int i = 0; i < str.size(); ++i) {
            if (str[i] == '0') {
                m++;
            }
            else if (str[i] == '1') {
                n++;
            }
        }
        vector<int>vec;
        vec.push_back(m);
        vec.push_back(n);
        return vec;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值