Happy new year from Suzy Day43 | 动态规划 写了好久啊

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

题目

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

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

如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 0。

solution

class Solution:
    def lastStoneWeightII(self, stones: List[int]) -> int:
        weight_sum=sum(stones)
        target=weight_sum//2
        target2=weight_sum-target
        #思路是:目标将所有的石头分成两堆(target1和target2)
        #尽量把所有的石头分成sum和靠近target,剩余的就是另外一堆
        #ans即为abs((sum-dp[target])-dp[target])
        package=[0]*3000
        dp=[]
        for i in range(len(stones)):dp.append(package.copy())

        for i in range(len(stones)):dp[i][0]=0
        for j in range(len(package)):dp[0][j]+=stones[0]

        for i in range(len(stones)):
            for j in range(target+1):
                if j>=stones[i]:
                    dp[i][j]=max(dp[i-1][j-stones[i]]+stones[i],dp[i-1][j])
                else:
                    dp[i][j]=dp[i-1][j]
        return abs((weight_sum-dp[len(stones)-1][target])-dp[len(stones)-1][target])




494 target sum

backpack method (ac)

import numpy as np
# use backtracking do it again
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        sum_array=sum(nums)
        if abs(target)>sum_array:return 0
        if (sum_array-target)%2!=0:return 0
        else:
            pos=(sum_array+target)//2
            neg=(sum_array-target)//2
        
        capacity=min(pos,neg)
        dp=np.zeros((len(nums)+1,capacity+1)) 
        # initialize
        # initialize
        # we add one more row to indicate that dp[i][j] means we use the first i items in the array and the initial dp[0][0] means we don't have item to put in to the bag -> no action. 
        dp[0][0]=1
        for i in range(1,len(dp)):
            for j in range(len(dp[0])):
                if j>=nums[i-1]:
                    dp[i][j]=int(dp[i-1][j]+dp[i-1][j-nums[i-1]])
                else:
                    dp[i][j]=dp[i-1][j]
        print(dp)
        return int(dp[-1][-1])

backtracking method (need try)

474. Ones and Zeroes

本质是是:01背包问题的多维背包版本
以下二维数组并不是表示是01背包的二维数组解法,而是一维滚动数组的二维背包版

from collections import Counter
import numpy as np
class Solution:
    def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
        strs_dict=dict()
        for i in range(len(strs)):
            strs_dict[i]=Counter(strs[i])
        print(strs_dict)
        dp=np.zeros((m+1,n+1))
        # dp[i][j] means 
        for k in range(len(strs)):
            if '0' in strs_dict[k]: zeronum=strs_dict[k]['0']
            else:zeronum=0
            if '1' in strs_dict[k]:onenum=strs_dict[k]['1']
            else:onenum=0
            for i in range(m,zeronum-1,-1): # zeronum<=i<=m
                for j in range(n,onenum-1,-1):
                    dp[i][j]=max(dp[i][j],dp[i-zeronum][j-onenum]+1)
        # print(dp)
        return int(dp[m][n])

01背包问题总结

二维数组:dp[i][j]表示使用前i个物品,装容量为j的背包的最大价值

dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight(i)]+value(i))
先遍历物品,再遍历背包,反之亦可。
遍历背包的顺序可以正序也可以倒序

一维数组:dp[j]表示装容量为j的背包的最大价值

dp[j]=max(dp[j],dp[j-weight(i)]+value(i))

for k in range(len(strs)): # 遍历物品
    for i in range(m,zeronum-1,-1): # 遍历背包 倒序
        for j in range(n,onenum-1,-1):
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值