【Kickstart】2019 Round B - Energy Stones

本文介绍了一种使用动态规划(DP)解决特定顺序依赖问题的方法。通过对物品进行适当的排序,并结合01背包问题的思路,文章提供了一种新颖且高效的解决方案。通过分析物品价值与消耗时间的关系,可以有效地确定最优顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解法

乍一看,如果是搜索的题,要枚举所有吃的顺序,那应该是O(n!)复杂度,估计吃不消
所以得往DP方向考虑,那么就有点像01背包问题,能量是物品的价值,而背包大小则是所有石头食用时间的总和
但是跟01背包问题不同的是,最后的能量和吃的顺序有关,而01背包里最后的能量跟物品放进背包的顺序无关,所以能拆解成子问题
想了半天也不会做

看完解答之后很有启发,对于这种跟顺序有关的情况,如果给定任何一个石头集合,我们都能排好一个顺序使得价值最大
那么先排序再做01背包就行了
这样,在决定物品i放不放的时候,背包里只需要考虑那些装入了应该排在它前面的物品的情况

对于大数据集来说,假如物品i和j相邻,分析可知它们谁排前面只取决于SLSL\frac{S}{L}LS更大的应该排前面,而对于L=0的那些石头,它们的SL\frac{S}{L}LS则取无穷大值

#!/usr/bin/env python
# -*- coding: utf-8 -*-

MOD = 10**9+7
import functools

S,E,L = [],[],[]

def cmp(i,j):
    global S,E,L
    if S[i]*L[j]<S[j]*L[i]:
        return -1
    if S[i]*L[j]>S[j]*L[i]:
        return 1
    return 0

if __name__ == '__main__':
    t = int(input())
    for _ in range(1, t + 1):
        n = int(input())
        S, E, L = [], [], []
        for i in range(n):
            s,e,l = map(int,input().split())
            S.append(s)
            E.append(e)
            L.append(l)
        rank = list(sorted(range(n),key=functools.cmp_to_key(cmp)))
        T = sum(S)
        f = [0]*(T+1)
        for i in range(n):
            for t in range(T,S[rank[i]]-1,-1):
                eatTime = t-S[rank[i]]
                energy = max(E[rank[i]]-L[rank[i]]*eatTime,0)
                if energy>0:
                    f[t] = max(f[t],f[t-S[rank[i]]]+energy)
        print("Case #{}: {}".format(_, max(f)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值