[路飞]_移除石子的最大得分

160 阅读2分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战

leetcode-1753 移除石子的最大得分

题目介绍

你正在玩一个单人游戏,面前放置着大小分别为 abc三堆 石子。

每回合你都要从两个 不同的非空堆 中取出一颗石子,并在得分上加 1 分。当存在 两个或更多 的空堆时,游戏停止。

给你三个整数 abc ,返回可以得到的 最大分数

示例

输入:a = 2, b = 4, c = 6
输出:6
解释:石子起始状态是 (2, 4, 6) ,最优的一组操作是:
- 从第一和第三堆取,石子状态现在是 (1, 4, 5)
- 从第一和第三堆取,石子状态现在是 (0, 4, 4)
- 从第二和第三堆取,石子状态现在是 (0, 3, 3)
- 从第二和第三堆取,石子状态现在是 (0, 2, 2)
- 从第二和第三堆取,石子状态现在是 (0, 1, 1)
- 从第二和第三堆取,石子状态现在是 (0, 0, 0)
总分:6 分 。

提示:

  • 1 <= a, b, c <= 10^5

解题思路

这道题是简单的数学逻辑题,要想得到最大分数,就要让所有的石子都尽可能全部取出,以下提供两种方案:

方案一

优先尽可能清空数量最少的一堆石子,然后再尽可能清空其他两堆石头

步骤

  1. 比较三堆石子的大小,调整三堆石子的位置,使 a 为最小的一堆,b 为次小的一堆,c 为最大的一堆
  2. 计算 c 堆石子比 b 堆石子多的数量 num1
  3. 如果 num1 大于等于 a 堆石子的数量,说明 a 堆石子 + b 堆石子 的数量小于等于 c 堆石子的数量,那么最大分数就是 a + b
  4. 如果 num1 小于 a 堆石子的数量
  • 先清空 num1 部分,分数加上 num1,此时 bc 的石子数相同
  • 如果 a 剩余部分石子的数量 num2 是奇数,则减去 1 个石子,然后将 a 堆石子由 bc 各清空一半,分数加上 num2
  • 最后将 bc 一一取出,分数加上 b - (num2 / 2)
  1. 得出最大分数

解题代码

var maximumScore = function(a, b, c) {
    if (a > b) [a, b] = [b, a]
    if (a > c) [a, c] = [c, a]
    if (b > c) [b, c] = [c, b]
    let grade = 0
    let num1 = c - b
    if (num1 > a) {
        grade = grade + a + b
    } else {
        grade += num1
        let num2 = a - num1
        if (num2 % 2 === 1) num2 -= 1
        grade = grade + num2
        grade = grade + (b - num2 / 2)
    }
    return grade
};

方案二

优先尽可能清空数量最大的一堆石子,然后再请可能清空其他两堆石头

步骤

  1. 比较三堆石子的大小,调整三堆石子的位置,使 a 为最小的一堆,b 为次小的一堆,c 为最大的一堆
  2. 如果 a + b 的数量小于等于 c,那么最大只能清空 a 堆和 b 堆,最大分数为 a + b
  3. 如果 a + b 的数量大于 c
  • 先清空 c 堆的数量,使得 a 堆和 b堆剩下的石子数量相差小于 1,此时分数加上 c 堆石子的数量
  • 如果 ab 的石子数相差 1,减去 1 个石子
  • 分数加上剩下石子数量总和的一半
  1. 得出最大分数

解题代码

var maximumScore = function(a, b, c) {
    if (a > b) [a, b] = [b, a]
    if (a > c) [a, c] = [c, a]
    if (b > c) [b, c] = [c, b]
    let grade = 0
    if (a + b <= c) {
        grade += a + b
    } else {
        let num = (a + b) - c
        if (num % 2 === 1) num -= 1
        grade += c
        grade += num / 2
    }
    return grade
};