leetcode956

最高的广告牌:找两个相同子集的最大和,砝码问题

你正在安装一个广告牌,并希望它高度最大。这块广告牌将有两个钢制支架,两边各一个。每个钢支架的高度必须相等。你有一堆可以焊接在一起的钢筋 rods。举个例子,如果钢筋的长度为 1、2 和 3,则可以将它们焊接在一起形成长度为 6 的支架。返回广告牌的最大可能安装高度。如果没法安装广告牌,请返回 0。

在这里插入图片描述

solution
  • 可以将问题简化为:给每个元素加上(0,-1,1)的系数,使得和为0,令系数为1的元素之和最大。
  • 解决思路:维护一个DP[key]: 表示 两根柱子差为 key 时的最长公共长度。这里为了减少内存,使用字典来进行保存。
  • 初始状态:当key=d时,如下图,此时的DP[key]=DP[d]=len(red):
    在这里插入图片描述
    • 若此时来了一个新的柱子长度为 x,x被加在了长的那一根柱子上: D P [ k e y + x ] = m a x ( D P [ k e y ] , D P [ k e y + x ] ) DP[key+x] = max(DP[key],DP[key+x]) DP[key+x]=max(DP[key],DP[key+x]) , 相当于说 红色的长度没有变
      在这里插入图片描述
    • 若此时来了一个新的柱子长度为 x,x被加在了短的那一根柱子上: D P [ a b s ( k e y − x ) ] = m a x ( m e m . g e t ( a b s ( k e y − x ) , 0 ) , D P [ k e y ] + m i n ( k e y , x ) ) DP[abs(key-x)]=max(mem.get(abs(key-x),0),DP[key]+min(key,x)) DP[abs(keyx)]=max(mem.get(abs(keyx),0),DP[key]+min(key,x)) 取abs是因为存在 d > x d>x d>x d < x d<x d<x 的情况:
      在这里插入图片描述
      在这里插入图片描述
class Solution(object):
    def tallestBillboard(self, rods):
        """
        :type rods: List[int]
        :rtype: int
        """
        #DP[key]:表示差为key的最大公共长度
        mem={0:0}
        
        for x in rods:
            cur = mem.copy()
            for key,val in cur.items():
                    ##mem.get(key+x,0)):从 mem 中取 (key+x) 如果有这个key就取,没有则返回0
                    mem[key+x] = max(mem.get(key+x,0),val)
                    mem[abs(key-x)]=max(mem.get(abs(key-x),0),val+min(key,x))
        # print(mem)
        return mem[0]
             
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值