2022-04-29:厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子。 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子。 如果剩余橘子数 n 能被

2022-04-29:厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子:
吃掉一个橘子。
如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子。
如果剩余橘子数 n 能被 3 整除,那么你可以吃掉 2*(n/3) 个橘子。
每天你只能从以上 3 种方案中选择一种方案。
请你返回吃掉所有 n 个橘子的最少天数。
输入:n = 10
输出:4
解释:你总共有 10 个橘子。
第 1 天:吃 1 个橘子,剩余橘子数 10 - 1 = 9。
第 2 天:吃 6 个橘子,剩余橘子数 9 - 2*(9/3) = 9 - 6 = 3。(9 可以被 3 整除)
第 3 天:吃 2 个橘子,剩余橘子数 3 - 2*(3/3) = 3 - 2 = 1。
第 4 天:吃掉最后 1 个橘子,剩余橘子数 1 - 1 = 0。
你需要至少 4 天吃掉 10 个橘子。
力扣1553. 吃掉 N 个橘子的最少天数。
来自腾讯。

答案2022-04-29:

能按比例吃的时候,绝不一个一个吃。递归。1/3和1/2取最小值。

代码用rust编写。代码如下:

use std::collections::HashMap;

fn main() {
    // 所有的答案都填在这个表里
    // dp这个表对所有的过程共用
    // 左神代码里,dp是全局变量。rust里没找到实现的方法。故采用传参的方式。
    let mut dp: HashMap<isize, isize> = HashMap::new();
    let n: isize = 10;
    let ans = min_days(n, &mut dp);
    println!("ans = {}", ans);
}

fn min_days(n: isize, dp: &mut HashMap<isize, isize>) -> isize {
    if n <= 1 {
        return n;
    }
    if let Some(x) = dp.get(&n) {
        return *x;
    }

    // 1) 吃掉一个橘子
    // 2) 如果n能被2整除,吃掉一半的橘子,剩下一半
    // 3) 如果n能被3正数,吃掉三分之二的橘子,剩下三分之一
    // 因为方法2)和3),是按比例吃橘子,所以必然会非常快
    // 所以,决策如下:
    // 可能性1:为了使用2)方法,先把橘子吃成2的整数倍,然后直接干掉一半,剩下的n/2调用递归
    // 即,n % 2 + 1 + minDays(n/2)
    // 可能性2:为了使用3)方法,先把橘子吃成3的整数倍,然后直接干掉三分之二,剩下的n/3调用递归
    // 即,n % 3 + 1 + minDays(n/3)
    // 至于方法1),完全是为了这两种可能性服务的,因为能按比例吃,肯定比一个一个吃快(显而易见的贪心)
    let ans = get_min(
        n % 2 + 1 + min_days(n / 2, dp),
        n % 3 + 1 + min_days(n / 3, dp),
    );
    dp.insert(n, ans);
    return ans;
}

fn get_min(a: isize, b: isize) -> isize {
    if a < b {
        a
    } else {
        b
    }
}

执行结果如下:

在这里插入图片描述


左神java代码

posted @   福大大架构师每日一题  阅读(41)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
历史上的今天:
2021-04-29 2021-04-29:给定一个数组 arr,代表一排有分数的气球。每打爆一个气球都能获得分数,假设打爆气 球 的分数为 X,获得分数的规则如下: 1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆
点击右上角即可分享
微信分享提示