AcWing 背包相关问题 734. 能量石

'''
先用贪心进行排序,能量损失小的石头先选取,
在排序后的序列上进行01背包
'''

T = int(input())

from functools import total_ordering


@total_ordering
class stone:
    def __init__(self, s, e, l):
        self.s = s
        self.e = e
        self.l = l

    def __eq__(self, other):
        return (self.s, self.e, self.l) == (other.s, other.e, other.l)

    def __lt__(self, other):
        val1 = self.l * other.s
        val2 = other.l * self.s
        return val1 < val2

    def __repr__(self):
        return f'{self.s},{self.e},{self.l}'


for case_id in range(1, T + 1):
    N = int(input())
    arr = []
    for i in range(N):
        s, e, l = map(int, input().split())
        arr.append(stone(s, e, l))

    # 首先进行排序, 最后的答案一定是在排序之后的序列中进行01背包
    arr.sort()
    total_j = sum([stone.s for stone in arr])

    # dp(i, j) 表示在前i种石头中做选择,剩余时间为j的约束下所有选法中最大总价值的数值
    dp = [0] * (total_j + 1)
    for i in range(N):
        for j in range(total_j, -1, -1):
            left_e = max(arr[i].e - (total_j - j) * arr[i].l, 0)
            if i == 0:
                dp[j] = left_e if j >= arr[i].s else 0
            else:
                if j >= arr[i].s:
                    dp[j] = max(dp[j], dp[j - arr[i].s] + left_e)
    print(f'Case #{case_id}: {dp[total_j]}')

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值