代码随想录算法训练营第三十五天|卡玛网46. 携带研究材料、leetcode416. 分割等和子集
1 卡玛网46. 携带研究材料二维方法
题目链接:46. 携带研究材料(第六期模拟笔试)
文章链接:代码随想录
视频链接:带你学透0-1背包问题!| 关于背包问题,你不清楚的地方,这里都讲了!| 动态规划经典问题 | 数据结构与算法_哔哩哔哩_bilibili
思路:真的就是不理解,我是理解不了这道题目的,听了视频理解一些了,然后自己做的时候我还是会迷糊,写不出来,但是呢整体理解是明白了
1.1 视频后的做法
其实绕的地方就是这个值和重量是怎么来的,然后看了一遍视频,自己再尝试敲了一遍,感觉理解的更深刻一点了
n,bagweight = map(int,input().split())
weight = list(map(int,input().split()))
value = list(map(int,input().split()))
dp = [[0]*(bagweight+1) for _ in range(n)]
for j in range(weight[0],bagweight+1):
dp[0][j] = value[0]
for i in range(1,n):
for j in range(bagweight+1):
if j<weight[i]:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i])
print(dp[n-1][bagweight])
1.2 本题小结
- 这道题目就是开始不理解下标的含义以及价值和重量的关系,然后就先看视频,视频看了以后还是有不会的就写题看讲解,看了以后就比较清楚了
- 主要就是这个值的一个关系吧,虽然是自己写的,但是希望下次我会写的更好
2 卡玛网46. 携带研究材料一维方法
题目链接:46. 携带研究材料(第六期模拟笔试)
文章链接:代码随想录
视频链接:带你学透01背包问题(滚动数组篇) | 从此对背包问题不再迷茫!_哔哩哔哩_bilibili
思路:就是再看了一遍,然后理解吧,,,但是呢其实也没有很通透,希望下一次我能彻底明白吧
2.1 视频后的思路
这道题,就是主打一个靠想象,想出来的吧,但是其实自己试验的时候就明白了为什么重量循环的时候要选择weight[i]-1
,如果是-1
的话,会导致前面是0的变成了之前的数值,其实这里是0
n,bagweight = map(int,input().split())
weight = list(map(int,input().split()))
value = list(map(int,input().split()))
dp = [0]*(bagweight+1)
dp[0] = 0
for i in range(n):
for j in range(bagweight,weight[i]-1,-1):
dp[j] = max(dp[j],dp[j-weight[i]]+value[i])
print(dp[bagweight])
2.2 本题小结
- 这道题目的方法,开始我是不理解为什么要加第一层循环,我以为压缩就是第一层循环就已经压缩没有了,哈哈哈哈哈哈,最后发现自己的想法有些天真了
- 最后自己做错了,再回来理解的时候,就是自己不理解的就明白了吧,虽然做的不好,但是也是尝试了
3 leetcode416. 分割等和子集
题目链接:416. 分割等和子集 - 力扣(LeetCode)
文章链接:代码随想录
视频链接:动态规划之背包问题,这个包能装满吗?| LeetCode:416.分割等和子集_哔哩哔哩_bilibili
思路:其实我觉得nums
相当于weight,这道题目的种类为2,因为是两个子集是否相等;
3.1 自己的方法
看了视频2分钟明白了怎么写,但是可能有优化的地方,就是开始不知道背包的重量应该初始化成多少,分割子集其实就是找子集中两个数据的值等于中间数即可
class Solution:
def canPartition(self, nums: List[int]) -> bool:
all_weight = sum(nums)
bag_weight = all_weight//2
if all_weight%2 !=0:
return False
dp = [0]*(bag_weight+1)
dp[0] = 0
for i in range(len(nums)):
for j in range(bag_weight,nums[i]-1,-1):
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i])
if dp[j] == bag_weight:
return True
return False
3.2 视频后的思路
其实和我的是一样的,就是返回值会放的地方不同
class Solution:
def canPartition(self, nums: List[int]) -> bool:
if sum(nums)%2!=0:
return False
bag_weight = sum(nums)//2
dp = [0]*(bag_weight+1)
dp[0] = 0
for i in range(len(nums)):
for j in range(bag_weight,nums[i]-1,-1):
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i])
if dp[bag_weight] == bag_weight:
return True
return False
3.3 本题小结
- 这道题目,开始就是不知道背包的总重量应该是多少,怎么都没想到一半就是正确的了,所以就不知道怎么写,看视频说了这一点以后,就立刻写了
- 怎么说呢,感觉还是实验的太少了,多去写多去看吧
4 今日小结
- 看来还是需要多去练习的,每天尝试几道题我的感觉就会不一样,终于又学会了一种问题的方法,突然发现NP问题的前身可能就是这么一步步推到出来的吧
- 希望接下来的自己,可以逐步向上,越来越顺畅,越来越会这些题目,加油吧