【动态规划专栏】背包问题:1049. 最后一块石头的重量 II

简介: 【动态规划专栏】背包问题:1049. 最后一块石头的重量 II


题目来源

本题来源为:

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

题目描述

有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。

每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:

如果 x == y,那么两块石头都会被完全粉碎;

如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。

最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0。

算法原理

本题的难点还是在于转化,将问题转化成目标和问题

1.状态表示

经验+题目要求

对于本题而言就是:

dp[i][j]表示:从前i个数中选,总和不超过j,此时的最大和

2.状态转移方程

问题已经转化成了01背包问题,分析跟01背包问题一样

因此状态方程为:

dp[i][j]=dp[i-1][j];
 if(j>=stones[i-1])
dp[i][j]=max(dp[i][j],dp[i-1][j-
stones[i1]]+stones[i-1]);

3.初始化

4.填表顺序

从上往下填买没一行

5.返回值

代码实现

动态规划的代码基本就是固定的四步:

1.创建dp表
2.初始化
3.填表
4.返回值

本题完整代码实现:

class Solution 
{
public:
    int lastStoneWeightII(vector<int>& stones) 
    {
        int sum=0;
        for(auto x:stones)
        sum+=x;
        int n=stones.size();
        int m=sum/2;
        //创建dp表
        vector<vector<int>> dp(n+1,vector<int>(m+1));
        //填表
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                dp[i][j]=dp[i-1][j];
                if(j>=stones[i-1])
                    dp[i][j]=max(dp[i][j],dp[i-1][j-stones[i-1]]+stones[i-1]);
            }
        }
        //返回值
        return sum-2*dp[n][m];
    }
};

空间优化

代码实现:

class Solution 
{
public:
    int lastStoneWeightII(vector<int>& stones) 
    {
        int sum=0;
        for(auto x:stones)
        sum+=x;
        int n=stones.size();
        int m=sum/2;
        //创建dp表
        vector<int> dp(m+1);
        //填表
        for(int i=1;i<=n;i++)
        {
            for(int j=m;j>=stones[i-1];j--)
            {
                dp[j]=max(dp[j],dp[j-stones[i-1]]+stones[i-1]);
            }
        }
        //返回值
        return sum-2*dp[m];
    }
};
相关文章
|
7月前
|
算法
【动态规划专栏】背包问题:01背包
【动态规划专栏】背包问题:01背包
86 0
|
6月前
|
算法 程序员
程序员必知:动态规划——背包问题1:01背包
程序员必知:动态规划——背包问题1:01背包
39 0
|
7月前
|
Java
leetcode-1049. 最后一块石头的重量 II
leetcode-1049. 最后一块石头的重量 II
57 0
动态规划入门01背包
基本思路: 1.n物品个数,m为背包体积,使用w[i]记录权值,v[i]记录体积,f[i][j]记录选择前i个物体,在不超过j体积下的最优解 最终答案就是f[n][m]; 2.f[i][j]的状态依赖于之前的状态;即f[i[][j]依赖于f[i - 1][j]的状态;也可以理解为所有的状态由f[0][j]推得 f[i][j]的状态不好算出来,但是f[0][j]的状态必定为0,由f[0][j]可以算出f[1][j]的,由f[1][j]又可算出f[2][j]的递推可得出全部。f[1][1] f[2][2] f[3][3]他们每个都减去第i个物品的权值最大值仍不变,最后在加上w[i]即可 即( f[
64 0
|
算法 C语言 C++
【动态规划】多重背包问题,分组背包问题
与完全背包问题不同的是,每种东西都是有限件,前两种状态就不再过多赘述
151 4
动态规划——多重背包、分组背包
动态规划——多重背包、分组背包
65 0
动态规划:分组背包问题
动态规划:分组背包问题
93 0
动态规划:多重背包问题
动态规划:多重背包问题
77 0
|
测试技术 容器
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
228 0
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
leetcode 1049 最后一块石头的重量
leetcode 1049 最后一块石头的重量
95 0
leetcode 1049 最后一块石头的重量