【代码随想录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]));

    }
};
相关推荐
仙俊红1 小时前
LeetCode487周赛T2,删除子数组后的最终元素
数据结构·算法
-dzk-7 小时前
【代码随想录】LC 59.螺旋矩阵 II
c++·线性代数·算法·矩阵·模拟
风筝在晴天搁浅8 小时前
hot100 78.子集
java·算法
Jasmine_llq8 小时前
《P4587 [FJOI2016] 神秘数》
算法·倍增思想·稀疏表(st 表)·前缀和数组(解决静态区间和查询·st表核心实现高效预处理和查询·预处理优化(提前计算所需信息·快速io提升大规模数据读写效率
超级大只老咪8 小时前
快速进制转换
笔记·算法
m0_706653238 小时前
C++编译期数组操作
开发语言·c++·算法
故事和你918 小时前
sdut-Java面向对象-06 继承和多态、抽象类和接口(函数题:10-18题)
java·开发语言·算法·面向对象·基础语法·继承和多态·抽象类和接口
qq_423233909 小时前
C++与Python混合编程实战
开发语言·c++·算法
TracyCoder1239 小时前
LeetCode Hot100(19/100)——206. 反转链表
算法·leetcode
m0_715575349 小时前
分布式任务调度系统
开发语言·c++·算法