leetcode2412. 完成所有交易的初始最少钱数(可恶啊

题目描述

给你一个下标从 0 0 0开始的二维整数数组 t r a n s a c t i o n s transactions transactions,其中 t r a n s a c t i o n s [ i ] = [ c o s t i , c a s h b a c k i ] transactions[i]=[cost_i, cashback_i] transactions[i]=[costi,cashbacki]
数组描述了若干笔交易。其中每笔交易必须以某种顺序恰好完成一次。在任意一个时刻,你有一定数目的钱 m o n e y money money,为了完成交易 i i i m o n e y > = c o s t i money>=cost_i money>=costi这个条件必须为真。执行交易后,你的钱数 m o n e y money money变成 m o n e y − c o s t i + c a s h b a c k i money-cost_i+cashback_i moneycosti+cashbacki。请你返回任意一种交易顺序下,你都能完成所有交易的最少钱数 m o n e y money money是多少。

示例1

输入: t r a n s a c t i o n s transactions transactions = [ [ 2 , 1 ] , [ 5 , 0 ] , [ 4 , 2 ] ] [ [2,1], [5,0], [4,2] ] [[2,1],[5,0],[4,2]]
输出: 10 10 10
解释:
刚开始 m o n e y = 10 money = 10 money=10,交易可以以任意顺序进行。
可以证明如果 m o n e y < 10 money < 10 money<10,那么某些交易无法进行。

示例2

输入: t r a n s a c t i o n s = [ [ 3 , 0 ] , [ 0 , 3 ] ] transactions = [ [3,0],[0,3] ] transactions=[[3,0],[0,3]]
输出: 3 3 3
解释:
1.如果交易执行的顺序是 [ [ 3 , 0 ] , [ 0 , 3 ] ] [[3,0],[0,3]] [[3,0],[0,3]],完成所有交易需要的最少钱数是 3 3 3
2.如果交易执行的顺序是 [ [ 0 , 3 ] , [ 3 , 0 ] ] [[0,3],[3,0]] [[0,3],[3,0]],完成所有交易需要的最少钱数是 0 0 0
所以,刚开始钱数为 3 3 3,任意顺序下交易都可以全部完成。

提示

  • 1 < = t r a n s a c t i o n s . l e n g t h < = 1 0 5 1 <= transactions.length <= 10^5 1<=transactions.length<=105
  • t r a n s a c t i o n s [ i ] . l e n g t h = = 2 transactions[i].length == 2 transactions[i].length==2
  • 0 < = c o s t i , c a s h b a c k i < = 1 0 9 0 <= cost_i, cashback_i <= 10^9 0<=costi,cashbacki<=109

题解&碎碎念

题目倒是很简单,很容易能看懂,在 l e e t c o d e leetcode leetcode里是困难题,一开始以为是 D P DP DP,看了题解才发现是贪心(啊啊啊啊啊

  • 题目要算的是任意情况下的最初 m o n e y money money,也就是要算在最差的情况下的 m o n e y money money
  • 最差的情况,即先亏损后盈利(也是就是先算 c o s t − c a s h b a c k > 0 cost-cashback>0 costcashback>0的情况,先不断地亏钱亏钱亏钱)
  • 在先亏损后盈利的情况下,有两个特殊的地方,即最后一次亏损和第一次盈利
  • 先说第一次盈利,如果能盈利的交易是五个,且它的 c o s t cost cost 3 3 3 8 8 8 1 1 1 5 5 5 6 6 6,那么我们希望在最后一次亏损时剩下的钱应该大于等于 8 8 8,才够后续的交易
  • 再说最后一次亏损,此时的 c a s h b a c k cashback cashback一定是最大的,因为在亏损时,我们一定希望前期亏损越大越好,前期亏损越大,那么留在手里的 m o n e y money money就越少,情况也就越差
  • 此时就可知,当整体交易有盈利交易时, m o n e y = money= money=全部亏损的金额 + + +盈利时最大的 c o s t cost cost
  • 当整体交易都是亏损交易时,由于我们计划一次性计算所有亏损的金额,需要再重新计算最后一次交易时的金额,即全部亏损的金额 − ( c o s t + c a s h b a c k ) + c o s t -(cost+cashback)+cost (cost+cashback)+cost,即 m o n e y = money= money=全部亏损的金额 + + +亏损时最大的 c a s h b a c k cashback cashback
  • l e e t c o d e leetcode leetcode的官方题解说的是,如果当前交易是盈利交易或是亏损交易时,则xxxxx,但是我发现如果只说当前,对照着代码有点理解不上去,因此我就改为整体交易是盈利交易或是亏损交易时,此时除了计算全部亏损的金额,还要在每一次遍历时计算最大的 c o s t cost cost c a s h b a c k cashback cashback,这里不判断到底是盈利还是亏损,通过 m i n ( c o s t , c a s h b a c k ) min(cost, cashback) min(cost,cashback)的方式获取即可
class Solution {
public:
    long long minimumMoney(vector<vector<int>>& transactions) {
        long long sum_lost=0;
        int c=0;
        for (auto t: transactions) {
            int cost=t[0], cash=t[1];
            if (cost>cash) {
                sum_lost+=cost-cash;
            }
            c=max(c, min(cost, cash));
        }
        return c+sum_lost;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值