动态规划----Ones and Zeroes

本文介绍了一种使用动态规划(DP)解决特定字符串组合问题的方法。该问题要求利用给定数量的0和1来形成尽可能多的指定字符串。文章详细解释了如何构建DP数组,并给出了C++实现代码。

题目描述:

In the computer world, use restricted resource you have to generate maximum benefit is what we always want to pursue.

For now, suppose you are a dominator of m 0s and n 1s respectively. On the other hand, there is an array with strings consisting of only 0s and 1s.

Now your task is to find the maximum number of strings that you can form with given m 0s and n 1s. Each 0 and 1 can be used at most once.

Note:

The given numbers of 0s and 1s will both not exceed 100

The size of given string array won't exceed 600.

题目的意思就是给你m个0,n个1.和一堆字符串。看给定个数的0和1最多能组成多少个给定的字符串。注意:也就是组成的字符串中0的总数为m,1的总数为n。

这道题是一道典型的应用DP来解的题,如果我们看到这种求总数,而不是列出所有情况的题,十有八九都是用DP来解,重中之重就是在于找出递推式。如果你第一反应没有想到用DP来做,想得是用贪心算法来做,比如先给字符串数组排个序,让长度小的字符串在前面,然后遍历每个字符串,遇到0或者1就将对应的m和n的值减小,这种方法在有的时候是不对的,比如对于{"11", "01", "10"},m=2,n=2这个例子,我们将遍历完“11”的时候,把1用完了,那么对于后面两个字符串就没法处理了,而其实正确的答案是应该组成后面两个字符串才对。所以我们需要建立一个二位的DP数组,其中dp[i][j]表示有i个0和j个1时能组成的最多字符串的个数,而对于当前遍历到的字符串,我们统计出其中0和1的个数为zeros和ones,然后dp[i - zeros][j - ones]表示当前的i和j减去zeros和ones之前能拼成字符串的个数,那么加上当前的zeros和ones就是当前dp[i][j]可以达到的个数,我们跟其原有数值对比取较大值即可,所以递推式如下:

dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1);

class Solution {
public:
    int findMaxForm(vector<string>& strs, int m, int n) {
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
        for (string str : strs) {
            int zeros = 0, ones = 0;
            for (char c : str) (c == '0') ? ++zeros : ++ones;
            for (int i = m; i >= zeros; --i) {
                for (int j = n; j >= ones; --j) {
                    dp[i][j] = max(dp[i][j], dp[i - zeros][j - ones] + 1);
                }
            }
            printVec(dp);
        }
        return dp[m][n];
    }
};

转载于:https://www.cnblogs.com/maowuyu-xb/p/6426372.html

在MATLAB中实现部分0-1规划(Partially Integer Linear Programming, PILP),你可以使用optimization toolbox中的`linprog`函数配合些额外步骤。部分0-1规划是指目标函数和约束条件都是线性的,但是变量中有部分需要是整数,其余可以是连续的。 以下是基本步骤: 1. **问题描述**: - 定义目标函数 `c` 和线性不等式约束 `Aeq*x <= beq` 或 `A*x <= b`,其中 `x` 是决策变量向量。 - 确定整数变量向量 `ix`,其他变量 `rx` 是连续的。 2. **转换为标准形式**: - 如果有等于约束 `Aeq` 和 `beq`,首先解出无约束部分的最优解 `xcont`,然后将它们固定并添加剩余约束到新的 `A` 和 `b` 中。 3. **构造部分整数模型**: - 对于整数变量 `ix`,创建个二进制矩阵 `I`,表示哪些元素是整数(值为1)。 - 创建个额外的变量 `z`,它是个连续变量,并设置 `x(ix) = I(ix,:)*z`,这样 `z` 将控制整数变量取值。 4. **求解**: - 使用`linprog`函数,传入目标系数 `c`, 约束矩阵 `A`、上界 `b` 或下界 `-b`, 连续变量范围 `lb` 和 `ub`(如果有的话),以及二进制变量 `I`。 5. **检查结果**: - 检查优化后的解 `x`,看是否满足整数约束。如果没有达到期望的整数状态,可能需要调整初始值、算法选项或考虑更复杂的整数优化方法(如branch and bound)。 ```matlab % 示例: c = [1; 2]; % 目标函数 A = ...; % 线性不等式约束系数 b = ...; % 上界或下界 ix = 1:3; % 整数变量索引 I = sparse(ix, :) * ones(size(A, 2), 1); % 创建二进制矩阵 % 构造部分整数模型 A_new = [A; I]; b_new = [b; zeros(size(I, 1), 1)]; % 添加额外的约束 % 解决部分0-1问题 [x, fval, exitflag] = linprog(c, A_new, b_new, [], [], lb, ub); % 检查整数变量是否为0或1 if any(abs(round(x(ix)) - x(ix)) > eps) disp('部分整数变量未达到整数状态'); end ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值