将钱分给最多的儿童

标签: 贪心 数学

难度: Easy

给你一个整数 money ,表示你总共有的钱数(单位为美元)和另一个整数 children ,表示你要将钱分配给多少个儿童。

你需要按照如下规则分配:

  • 所有的钱都必须被分配。
  • 每个儿童至少获得 1 美元。
  • 没有人获得 4 美元。

请你按照上述规则分配金钱,并返回 最多 有多少个儿童获得 恰好 8 美元。如果没有任何分配方案,返回 -1 。

示例 1:

输入:money = 20, children = 3
输出:1
解释:
最多获得 8 美元的儿童数为 1 。一种分配方案为:
- 给第一个儿童分配 8 美元。
- 给第二个儿童分配 9 美元。
- 给第三个儿童分配 3 美元。
没有分配方案能让获得 8 美元的儿童数超过 1 。

示例 2:

输入:money = 16, children = 2
输出:2
解释:每个儿童都可以获得 8 美元。

提示:

  • 1 <= money <= 200
  • 2 <= children <= 30

Submission

运行时间: 22 ms

内存: 16.0 MB

class Solution:
    def distMoney(self, money: int, children: int) -> int:
        if money<children:
            return -1
        money-=children
        res=min(money//7,children)
        money-=7*res
        children-=res
        if (money==3 and children==1) or (children==0 and money>0):
            res-=1
        return res


Explain

此题解采用贪心策略,首先确保每个儿童至少得到1美元。然后尝试最大化获得8美元的儿童数量。首先,每个儿童至少分配1美元,然后计算剩余可用金额,尝试尽可能多地安排每个儿童获得8美元(每个儿童多分配7美元)。计算可以这样安排的最大儿童数量,然后从总金额中减去相应的值。如果剩余的钱正好为3美元且只剩一个儿童,或者没有剩余儿童但还有剩余金额,则需要从之前计算的结果中减去一个儿童,因为这表明无法将所有剩余金额分配给任何剩余的儿童而不违反规则。

时间复杂度: O(1)

空间复杂度: O(1)

class Solution:
    def distMoney(self, money: int, children: int) -> int:
        # 若总金额少于儿童数,无法每人至少分配1美元
        if money < children:
            return -1
        # 首先给每个儿童分配1美元,计算剩余金额
        money -= children
        # 尝试最多分配给每个儿童7美元额外(即总共8美元),计算能这样分配的最大儿童数
        res = min(money // 7, children)
        # 更新剩余金额和剩余儿童数
        money -= 7 * res
        children -= res
        # 处理特殊情况:若剩余3美元且剩余1个儿童,或无剩余儿童但有剩余金额
        if (money == 3 and children == 1) or (children == 0 and money > 0):
            res -= 1
        return res

Explore

题解中的算法设计确保每个儿童最少得到1美元,并尝试使他们尽可能得到8美元。通过这种方式,算法避免了分配4美元的情况。算法只考虑1美元和8美元两种情况,确保不出现给任何儿童分配4美元的情况。

选择每个儿童最初分配1美元是为了确保基本的公平性,每个儿童至少得到一些金额,符合题目要求。这也是为了简化后续的计算,一旦确保每个儿童至少得到1美元,剩余的金额可以用来尝试实现其他的优化条件,如尽量多的儿童获得8美元。

这种处理方式确实可能导致非最优的分配结果。因为减去一个已经计入的儿童意味着减少了能够接近题目要求的儿童数量。这是算法处理剩余情况的一种简化方式,但可能不是最优解,特别是在处理边界条件时。更优的处理可能需要更复杂的逻辑来确保所有剩余金额都能以最优方式分配。

在这种情况下,算法通过计算`money // 7`来确定最多能给多少儿童分配额外的7美元。这保证了算法不会尝试分配超出剩余金额的资金。计算得到的结果不会超过实际可用的额外金额或儿童数。如果剩余金额不足以给每个儿童分配额外的7美元,则只有部分儿童能得到额外的7美元,其余儿童仍然只能保持最初的1美元。