leetcode1553. 吃掉 N 个橘子的最少天数(Python3、c++)
文章目录
- leetcode1553. 吃掉 N 个橘子的最少天数
- 方法:递归+记忆化
- 思路:
- 代码:
- Python3:
- cpp:
- 结果:
leetcode1553. 吃掉 N 个橘子的最少天数
厨房里总共有 n
个橘子,你决定每一天选择如下方式之一吃这些橘子:
- 吃掉一个橘子。
- 如果剩余橘子数
n
能被 2 整除,那么你可以吃掉n/2
个橘子。 - 如果剩余橘子数
n
能被 3 整除,那么你可以吃掉2*(n/3)
个橘子。
每天你只能从以上 3 种方案中选择一种方案。
请你返回吃掉所有 n
个橘子的最少天数。
示例 1:
输入: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 个橘子。
示例 2:
输入:n = 6
输出:3
解释:你总共有 6 个橘子。
第 1 天:吃 3 个橘子,剩余橘子数 6 - 6/2 = 6 - 3 = 3。(6 可以被 2 整除)
第 2 天:吃 2 个橘子,剩余橘子数 3 - 2*(3/3) = 3 - 2 = 1。(3 可以被 3 整除)
第 3 天:吃掉剩余 1 个橘子,剩余橘子数 1 - 1 = 0。
你至少需要 3 天吃掉 6 个橘子。
示例 3:
输入:n = 1
输出:1
示例 4:
输入:n = 56
输出:6
提示:
1 <= n <= 2*10^9
方法:递归+记忆化
思路:
本题首先可以想到的方法就是动态规划。首先简洁概括一下题意,如果橘子数是3的倍数,那么可以吃一个,也可以吃完剩n/3个;如果是二的倍数,可以吃一个,也可以吃一半,剩n/2个;其他情况只能吃一个。
首先我们需要证明一个贪心的思想,如何选择可以吃的最快。首先假设有n个橘子,那么我们最慢的情况是每天只吃1个,那么需要n天。如果假设我们有k天只吃1个橘子,然后n-k满足是3的倍数,那么我们从n到(n-k)/3,一共用了k+1天。
**我们需要证明,这个k<3,即只要遇到3的倍数,我们就应该选择吃掉2/3的橘子,即比如有7个橘子,我们到6的时候就选择吃掉2/3的橘子;**而不是等到每天吃一个剩3的时候再选择,这就是贪心的思想。
- 下面我们进行证明,如果k >= 3,由上面的分析,**我们从n到(n-k)/3,一共用了k+1天。**因为k>=3,**我们可以在k-3的时候就吃掉2/3。**那么我们从n到(n-k)/3 + 1,一共需要k-2天,再只用一天吃掉一个橘子,就可以达到(n-k)/3。因此一共只用了k-1天。这就表明了当遇到3的倍数就吃掉2/3的橘子才是最优的选择,这就是贪心的思想。
与上面的想法一样,对于橘子数是2的倍数的时候,同样也是,只要遇到橘子数是2的倍数,那么就吃掉一半,也是贪心的思想。但是我们是应该选择遇到3的倍数吃掉2/3,还是遇到2的倍数吃掉一半,这两者之间无法比较。
因此,假设dp[n]表示将n个橘子吃掉需要的最少天数,那么这个值可能是找到2的倍数时候,也可能是找到3的倍数的时候。那么,我们可以得到状态转移方程:
dp[n]=min(n%3+dp[n/3],n%2+dp[n/2])+1dp[n] = min(n\%3\ + dp[n/3]\ ,n\%2 \ + dp[n/2]) + 1 dp[n]=min(n%3 +dp[n/3] ,n%2 +dp[n/2])+1
求解动态规划的方法有两种,一种是自顶而下的递归+记忆化的方法,另一种是自底而上的dp数组的方法。我们应该使用前者,因为对于dp数组,如果我们求dp[n],那么我们需要将0-n的所有dp值都求出,这里面会存在许多“只吃一个橘子”的操作,根据数据范围,时间和空间都无法承受。因此我们应该使用递归的方法,这样计算量会少很多。
代码:
Python3:
class Solution:def minDays(self, n: int) -> int:memo = {0:0,1:1}def dfs(n):if n in memo:return memo[n]ans = min(dfs(n//2)+n%2 , dfs(n//3)+n%3) + 1memo[n] = ansreturn ansreturn dfs(n)
cpp:
class Solution {public:unordered_map<int,int>m;//离散化int dfs(int i){if(i==0)return 0;//出口if(m.count(i))return m[i];//dpreturn m[i]=min({1+i%2+dfs(i/2),1+i%3+dfs(i/3),i});//分别对应/3,/2,-1.}int minDays(int n) {return dfs(n);}
};
结果:
leetcode1553. 吃掉 N 个橘子的最少天数(Python3、c++)相关推荐
- Leetcode1553. 吃掉 N 个橘子的最少天数
[力扣]1553. 吃掉 N 个橘子的最少天数 1.题目描述 厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子. 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n ...
- 力扣 1553. 吃掉 N 个橘子的最少天数 记忆化DFS|记忆化BFS|剪枝
吃掉 N 个橘子的最少天数 厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子. 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子. 如果剩余橘子数 n ...
- LeetCode 1553. 吃掉 N 个橘子的最少天数(BFS)
文章目录 1. 题目 2. 解题 1. 题目 厨房里总共有 n 个橘子,你决定每一天选择如下方式之一吃这些橘子: 吃掉一个橘子. 如果剩余橘子数 n 能被 2 整除,那么你可以吃掉 n/2 个橘子. ...
- LeetCode 1568. 使陆地分离的最少天数(DFS)
文章目录 1. 题目 2. 解题 1. 题目 给你一个由若干 0 和 1 组成的二维网格 grid ,其中 0 表示水,而 1 表示陆地. 岛屿由水平方向或竖直方向上相邻的 1 (陆地)连接形成. 如 ...
- leetode题库5438--制作 m 束花所需的最少天数
5438. 制作 m 束花所需的最少天数 给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k 朵花 . 花园中有 n 朵花, ...
- Leetcode_1482.制作m束花所需的最少天数
给你一个整数数组 bloomDay,以及两个整数 m 和 k . 现需要制作 m 束花.制作花束时,需要使用花园中 相邻的 k 朵花 . 花园中有 n 朵花,第 i 朵花会在 bloomDay[i] ...
- leetcode1568. 使陆地分离的最少天数(Python3、c++)
文章目录 leetcode1568. 使陆地分离的最少天数 方法:并查集 思路: 并查集: 求割点: 代码: Python3: cpp: 结果: leetcode1568. 使陆地分离的最少天数 给你 ...
- Leetcode 1482题 制作 m 束花所需的最少天数
Leetcode 1482题 制作 m 束花所需的最少天数 链接: 制作 m 束花所需的最少天数. 提交结果: 解题思路 本题主要采用二分查找的解题思路,范围为0到天数最大值,根据是否能组成相应数量的 ...
- 周末加餐 使陆地分离的最少天数
给你一个由若干 0 和 1 组成的二维网格 grid ,其中 0 表示水,而 1 表示陆地.岛屿由水平方向或竖直方向上相邻的 1(陆地)连接形成. 如果恰好只有一座岛屿 ,则认为陆地是连通的 :否则, ...
最新文章
- 算法导论课后习题解析 第四章 上
- 从Linux内核中获取真随机数【转】
- Ubuntu14.04重启网卡不生效
- 机器学习之路: python 实践 word2vec 词向量技术
- ALI的Tensorflow炼成与GAN科普
- 潜在狄利克雷分布(LDA)初探
- canvas笔记-使用canvas画圆及点阵的使用
- 电脑不能上网win7 解决办法
- 两个特征是独立好还是正相关好_【概率论与数理统计】第5期:随机变量的数字特征...
- 华为鸿蒙宣传悟空视频_给华为“鸿蒙”打Call,家居头条号探讨短片《悟空》获50万阅读...
- 性能优化–查找和解决僵尸对象
- STM32串口通信实验(学习笔记)
- 几个免费的英文文献的网站
- 如何使用c语言开发ebpf程序
- USB手机数据线充电线电源线出口办理CE认证的流程
- 你一定要收藏的全网最完整CAD快捷键大全!
- ps、ai超强辅助类插件,神器一样的存在
- servlet使用监听器统计网站在线人数
- SQL Server服务器名称
- SEO在网页中的应用