[leetcode] 1648. Sell Diminishing-Valued Colored Balls

Description

You have an inventory of different colored balls, and there is a customer that wants orders balls of any color.

The customer weirdly values the colored balls. Each colored ball’s value is the number of balls of that color you currently have in your inventory. For example, if you own 6 yellow balls, the customer would pay 6 for the first yellow ball. After the transaction, there are only 5 yellow balls left, so the next yellow ball is then valued at 5 (i.e., the value of the balls decreases as you sell more to the customer).

You are given an integer array, inventory, where inventory[i] represents the number of balls of the ith color that you initially own. You are also given an integer orders, which represents the total number of balls that the customer wants. You can sell the balls in any order.

Return the maximum total value that you can attain after selling orders colored balls. As the answer may be too large, return it modulo 109 + 7.

Example 1:

Input: inventory = [2,5], orders = 4
Output: 14
Explanation: Sell the 1st color 1 time (2) and the 2nd color 3 times (5 + 4 + 3).
The maximum total value is 2 + 5 + 4 + 3 = 14.

Example 2:

Input: inventory = [3,5], orders = 6
Output: 19
Explanation: Sell the 1st color 2 times (3 + 2) and the 2nd color 4 times (5 + 4 + 3 + 2).
The maximum total value is 3 + 2 + 5 + 4 + 3 + 2 = 19.

Example 3:

Input: inventory = [2,8,4,10,6], orders = 20
Output: 110

Example 4:

Input: inventory = [1000000000], orders = 1000000000
Output: 21
Explanation: Sell the 1st color 1000000000 times for a total value of 500000000500000000. 500000000500000000 modulo 109 + 7 = 21.

Constraints:

  • 1 <= inventory.length <= 105
  • 1 <= inventory[i] <= 109
  • 1 <= orders <= min(sum(inventory[i]), 109)

分析

题目的意思是:这道题给出了很多不同颜色的球,然后每卖出球的价值和它本身的数量有关。思路很直接,贪心的算法,每次取出数量多的球就能达到价值最大化,如果按照这个规则暴力破解的话,网上的人说的是超时,我也就没尝试。

  • 换一种思路,如果我知道每个球最多卖多少次的话就容易求出总的最大价值了,所以可以使用二分法找到卖出球数量的边界,二分的时候要保证orders大于等于0,把边界向左移动,即r=mid-1;否则的话需要把边界向右移动,即l=mid+1。
  • 求出边界l以后,我们就可用等差数列求和公式算出每个球卖了的价值,a1+a2+…+an=(a1+an)*n//2,orders进行更新
  • 如果orders还大于0,说明还可以再卖orders个球,就把l边界的数量的球取orders个卖掉就能达到最大价值了

代码

class Solution:
    def isValid(self,inventory,k,orders):
        for num in inventory:
            if(num>k):
                orders-=num-k
            if(orders<0):
                return False
        return orders>=0
        
    def maxProfit(self, inventory: List[int], orders: int) -> int:
        mod=10**9+7
        l=0
        r=max(inventory)
        while(l<=r):
            mid=l+(r-l)//2
            if(self.isValid(inventory,mid,orders)):
                r=mid-1
            else:
                l=mid+1
        res=0
        for num in inventory:
            if(num>l):
                a1=num
                an=l+1
                n=num-l
                res+=((a1+an)*n//2)%mod
                orders-=n
        if(orders>0):
            res+=l*orders
        res%=mod

参考文献

[leetcode题解] 第1648题Sell Diminishing Valued Colored Balls

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农民小飞侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值