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

    }
};
相关推荐
ゞ 正在缓冲99%…32 分钟前
leetcode1312.让字符串成为回文串的最少插入次数
数据结构·算法·leetcode·动态规划·记忆化搜索
七夜zippoe1 小时前
Rust `std::iter` 深度解析:`Iterator` Trait、适配器与性能
开发语言·算法·rust
寂静山林1 小时前
UVa 1464 Traffic Real Time Query System
算法
laocooon5238578861 小时前
寻找使a×b=c成立的最小进制数(2-16进制)
数据结构·算法
YY_TJJ1 小时前
算法题——图论
算法·深度优先·图论
默默的流星雨1 小时前
TARJAN相关
c++·算法·深度优先·图论
JJJJ_iii2 小时前
【机器学习11】决策树进阶、随机森林、XGBoost、模型对比
人工智能·python·神经网络·算法·决策树·随机森林·机器学习
别学LeetCode3 小时前
#leetcode#
leetcode
loong_XL3 小时前
AC自动机算法-字符串搜索算法:敏感词检测
开发语言·算法·c#
Xの哲學3 小时前
Linux Netlink全面解析:从原理到实践
linux·网络·算法·架构·边缘计算