5/14学习总结

今天补了下周末考的测试题,但是做到第三个动态规划的题就不行了,之前都还没学动态规划,今天稍微看了看,还是不太明白,但是懂了一些。

首先的话就是对于dp数组的介绍:

dp数组的含义:
dp[i][j]:[0,i]之间的物品任取放入容量为j的背包里。
不放物品i:dp[i-1][j]此时的i-1就表示[0,i-1]个物品也就是去除了i这个物品。
放物品i:dp[i-1][j-weight[i]]+value[i]
dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])

一般来说用一维数组更简单,但是更晦涩难懂。

今天就学了一下动态规划的01背包,做了两道题,

第一道:416. 分割等和子集 - 力扣(LeetCode)

对于01背包相关题的话首先确定几个方向。

  • 背包的体积为sum / 2
  • 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素是不可重复放入。   

如若都满足则就是01背包类的题目。对于这道题而言的话。

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

 其实就是依葫芦画瓢写01背包代码

对于另一道题:1049. 最后一块石头的重量 II - 力扣(LeetCode)​​​​​

 对于这道题的话其实也是01背包一类的题,但是这道题难得并不是01背包相关的代码,而是阅读完整道题后,不知道是使用01背包从而引起连锁反应,根本不知道怎么做。其实怎么想到是用01背包,就是想到把这一个数组分成两堆数值相似的值,再用大的去减去小的,最后得到得不就是最小值了吗。也就等同于01背包题了。

class Solution {
public:
    int lastStoneWeightII(vector<int>& stones) {
        int i,j,k,s,a,b,c,target;
        int sum=0;
        int n=stones.size();
        vector<int>dp(15001,0);
        for(i=0;i<n;i++)
        {
            sum+=stones[i];
        }
        target=sum/2;
        for(i=0;i<n;i++)
        for(j=target;j>=stones[i];j--)
        {
            dp[j]=max(dp[j],dp[j-stones[i]]+stones[i]);
        }
        return sum-dp[target]-dp[target];
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值