【代码随想录day 35】 力扣 1049. 最后一块石头的重量 II

视频讲解:https://www.bilibili.com/video/BV14M411C7oV/?vd_source=a935eaede74a204ec74fd041b917810c

文档讲解:https://programmercarl.com/1049.最后一块石头的重量II.html#思路

力扣题目:https://leetcode.cn/problems/last-stone-weight-ii/

这道题本质上还是个01背包问题,本质上可以计算背包容量为sum / 2 的背包最大能装多少价值的东西,sum - dp[j]即为另一半的价值,再减去dp[j]即为两边的差

  1. dp含义:dp[j]表示容量为j的背包能装0-i的物品的最大价值
  2. 递推公式:在一维数组的基础上进行更新dp[j] = max(dp[j], dp[j- stones[i]] + stones[i]);
  3. 初始化,可以同遍历一起,初始化为0
  4. 遍历。二维表中最上一行往最下一行遍历
  5. 打印数组
    一维写法:
cpp 复制代码
class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int sum = 0;
        for(int i : stones)
        {
            sum += i;
        }
        int target = sum / 2;
        //本质上是一个看是否能装满sum/2的题,
        //1. dp[j]含义:在容量为j的背包里stone[i]能装的最多的价值
        vector<int> dp(target + 1, 0);
        //2. 递推公式:dp[j] = max(dp[j], dp[j- stones[i]] + stones[i]);
        //3.初始化:初始化二维数组的最上一行和最左一列
        //4.遍历方式:从后往前
        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]);
    }
};

二维写法:

cpp 复制代码
int lastStoneWeightII(vector<int>& stones) {
        int sum = 0;
        for(int i : stones)
        {
            sum += i;
        }
        int target = sum / 2;
        //本质上是一个看是否能装满sum/2的题,
        //1. dp[i][j]含义:在容量为j的背包里stone能装的最多的价值
        vector<vector<int>> dp(stones.size(), vector<int>(target + 1, 0));
        //2. 递推公式:dp[i][j] = max(dp[i - 1][j], dp[i - 1][j- stones[i]] + stones[i]);
        //3.初始化:初始化二维数组的最上一行和最左一列
        for(int i = 0; i < stones.size(); ++i)
        {
            dp[i][0] = 0;
        }
        for(int j = 0; j <= target; ++j)
        {
            if(j >= stones[0])
            {
                dp[0][j] = stones[0];
            }
        }
        //遍历从上往下从左往右
        for(int i = 1; i < stones.size(); ++i)
        {
            for(int j = 1; j <= target; ++j)
            {
                if(j < stones[i])
                {
                    dp[i][j] = dp[i - 1][j];
                }
                else
                {
                    dp[i][j] = max(dp[i - 1][j], dp[i - 1][j- stones[i]] + stones[i]);
                }
                //cout << "i,j:" << dp[i][j] << endl;
            }
        }
        return (abs(sum - 2 * dp[stones.size() - 1][target]));

    }
};
相关推荐
gfdhy14 小时前
【c++】哈希算法深度解析:实现、核心作用与工业级应用
c语言·开发语言·c++·算法·密码学·哈希算法·哈希
百***060114 小时前
SpringMVC 请求参数接收
前端·javascript·算法
一个不知名程序员www15 小时前
算法学习入门---vector(C++)
c++·算法
云飞云共享云桌面16 小时前
无需配置传统电脑——智能装备工厂10个SolidWorks共享一台工作站
运维·服务器·前端·网络·算法·电脑
福尔摩斯张16 小时前
《C 语言指针从入门到精通:全面笔记 + 实战习题深度解析》(超详细)
linux·运维·服务器·c语言·开发语言·c++·算法
橘颂TA16 小时前
【剑斩OFFER】算法的暴力美学——两整数之和
算法·leetcode·职场和发展
Dream it possible!17 小时前
LeetCode 面试经典 150_二叉搜索树_二叉搜索树的最小绝对差(85_530_C++_简单)
c++·leetcode·面试
xxxxxxllllllshi17 小时前
【LeetCode Hot100----14-贪心算法(01-05),包含多种方法,详细思路与代码,让你一篇文章看懂所有!】
java·数据结构·算法·leetcode·贪心算法
前端小L17 小时前
图论专题(二十二):并查集的“逻辑审判”——判断「等式方程的可满足性」
算法·矩阵·深度优先·图论·宽度优先
铁手飞鹰17 小时前
二叉树(C语言,手撕)
c语言·数据结构·算法·二叉树·深度优先·广度优先