[Leetcode] 416. 分割等和子集、1049. 最后一块石头的重量 II、494. 目标和、474. 一和零

这篇具有很好参考价值的文章主要介绍了[Leetcode] 416. 分割等和子集、1049. 最后一块石头的重量 II、494. 目标和、474. 一和零。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

内容:今天复习下dp数组中的背包问题

分割等和子集 - 能否装满

最后一块石头 - 尽可能装满

目标和 - 有多少种方法装

一和零 - 装满背包有多少个物品

416. 分割等和子集

10背包:用/不用;有容量;有价值

dp[j] : 容量为j,最大价值为dp[j]

        重量和价值等价

dp[target] == target 属于装满

target = sum/2

递推公式:dp[j] = max(dp[j], dp[j-weight[i]]+value[i])

        状态转移方程:只有放和不放两种情况

dp[j] = max(dp[j], dp[j-nums[i]]+nums[i])

初始化:dp[0] = 0

其他(非零下标)=0

class Solution {
public:
    bool canPartition(vector<int>& nums) {
        int sum = 0;
        for(int num:nums) {
            sum += num;
        }
        if(sum%2!=0) {
            return false;
        }
        int target = sum/2;
        int size = 200*100/2 + 1;
        vector<int> dp(size, 0);
        for(int i=0; i<nums.size(); ++i) {
            for(int j=target; j>=nums[i]; --j) {
                dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]);
            }
        }
        return dp[target] == target;

    }
};

1049. 最后一块石头的重量 II

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int size = 30*100/2 + 1;
        vector<int> dp(size, 0);
        int sum = 0;
        for(int stone:stones) {
            sum += stone;
        }
        int target = sum/2;
        for(int i=0; i<stones.size(); ++i) {
            for(int j=target; j>=stones[i]; --j) {
                dp[j] = max(dp[j], dp[j-stones[i]]+stones[i]);
            }
        }
        return sum-2*dp[target];
    }
};

494. 目标和

假设加法的总和为x,那么减法对应的总和就是sum - x。

所以我们要求的是 x - (sum - x) = target

x = (target + sum) / 2

有多少种方法装满

dp[j]:装满背包容量为j,有dp[j]种方法

class Solution {
public:
    int findTargetSumWays(vector<int>& nums, int target) {
        int sum = 0;
        for(int num:nums) {
            sum += num;
        }
        if(abs(target)>sum) {
            return 0;
        }
        if((target+sum)%2 != 0) {
            return 0;
        }

        int bagSize = (target+sum) /2;
        vector<int> dp(bagSize+1, 0);
        dp[0] = 1;
        for(int i=0; i<nums.size(); ++i) {
            for(int j=bagSize; j>=nums[i]; --j) {
                dp[j] += dp[j-nums[i]];
            }
        }
        return dp[bagSize];
    }
};

474. 一和零

m个0,n个1的容器

装满这个背包(二维)最多几个物品

背包两个维度:dp[i][j] - i个0,j个1,最多装dp[i][j] 个物品

        三个变量

递推公式:dp[j] = max(dp[j], dp[j-weight[i]]+value[i])

重量:x个0,y个1 (用两个维度来形容物品重量)

最大容量:m个0,n个1

物品数量:dp[i-x][j-y] + 1

dp[i][j] = max(dp[i][j], dp[i-x][j-y] + 1)

dp[0][0] = 0

非零下标 = 0

先物品后重量文章来源地址https://www.toymoban.com/news/detail-571084.html

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 zeroNum =0;
            int oneNum = 0;
            for(char c:str) {
                if(c=='0') zeroNum++;
                else oneNum++;
            }
            for(int i=m; i>=zeroNum; --i) {
                for(int j=n; j>=oneNum; --j) {
                    dp[i][j] = max(dp[i][j], dp[i-zeroNum][j-oneNum]+1);
                }
            }
        }
        return dp[m][n];

    }
};

到了这里,关于[Leetcode] 416. 分割等和子集、1049. 最后一块石头的重量 II、494. 目标和、474. 一和零的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • LeetCode 1049 最后一块石头的重量 II

    题目: 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x = y。那么粉碎的可能结果如下: 如果 x == y,那么两块石头都会被完全粉碎; 如果 x != y,那么重

    2024年02月05日
    浏览(45)
  • Leetcode 416 分割等和子集

    题意理解 :         给你一个  只包含正整数  的  非空  数组  nums  。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。         即将数组的元素分成两组,每组数值=sum(nums)/2         若能分成这样的两组,则返回true,否则返回false      

    2024年02月01日
    浏览(44)
  • 【LeetCode】416.分割等和子集

    给你一个  只包含正整数  的  非空  数组  nums  。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 示例 2: 提示: 1 = nums.length = 200 1 = nums[i] = 100 实际上是求能否从背包里选取元素,使这些元素之和等于数组所有元素之和的一半。dp

    2024年02月11日
    浏览(36)
  • LeetCode416. 分割等和子集

    一、题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 示例 2: 提示: 1 = nums.length = 200 1 = nums[i] = 100 二、题解 方法一:0-1背包二维数组 步骤1:理解题目以及01 背包问题 在 01 背包问题中,

    2024年02月10日
    浏览(46)
  • ( 背包问题) 1049. 最后一块石头的重量 II ——【Leetcode每日一题】

    难度:中等 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出 任意两块石头 ,然后将它们一起粉碎。假设石头的重量分别为 x 和 y ,且 x = y 。那么粉碎的可能结果如下: 如果 x == y ,那么两块石头都会被完全粉碎; 如果 x !=

    2024年02月08日
    浏览(51)
  • 【算法与数据结构】1049、LeetCode 最后一块石头的重量 II

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题需要得到石头之间两两粉碎之后的最小值,那么一个简单的思路就是将这堆石头划分成大小相近的两小堆石头,然后粉碎,这样得到的结果必然是最优值。那么如何划分呢?我

    2024年01月21日
    浏览(48)
  • leetcode416. 分割等和子集(动态规划-java)

    来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/partition-equal-subset-sum 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。 示例 1: 输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。

    2024年02月11日
    浏览(37)
  • Day43|leetcode 1049.最后一块石头的重量II、494.目标和、474.一和零

    题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode) 视频链接:动态规划之背包问题,这个背包最多能装多少?LeetCode:1049.最后一块石头的重量II_哔哩哔哩_bilibili 有一堆石头,每块石头的重量都是正整数。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设

    2024年02月10日
    浏览(51)
  • 【算法与数据结构】416、LeetCode分割等和子集

    所有的LeetCode题解索引,可以看这篇文章——【算法和数据结构】LeetCode题解。    思路分析 :本题可以抽象成一个01背包的问题,关于01背包可以看【算法与数据结构】算法与数据结构知识点。 本题只需要求出数组的累积和,然后和的一半就可以视为背包的最大重量,目标

    2024年01月19日
    浏览(42)
  • 01背包问题-递推公式的自我理解与LeetCode 416. 分割等和子集

    学算法好痛苦,完全是对我智力的一次次折磨,看了好多博客,对二维dp数组的理解都是直接搬了代码随想录,搬了随想录又没详细解释,大家都是一眼看懂的吗,好吧() 如果有一个容量为 j 的这样的背包——一个独立的,容量为j的背包。(没把它理解为“剩余容量”) 对于

    2024年02月07日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包