一、题目
1、题目描述
厨房里总共有
n
个橘子,你决定每一天选择如下方式之一吃这些橘子:
- 吃掉一个橘子。
- 如果剩余橘子数
n
能被 2 整除,那么你可以吃掉n/2
个橘子。- 如果剩余橘子数
n
能被 3 整除,那么你可以吃掉2*(n/3)
个橘子。每天你只能从以上 3 种方案中选择一种方案。
请你返回吃掉所有
n
个橘子的最少天数。
2、接口描述
python3
class Solution:
def minDays(self, n: int) -> int:
cpp
class Solution {
public:
int minDays(int n) {
}
};
3、原题链接
二、解题报告
1、思路分析
显然操作1、2都要比一个一个减更优
因为当我们一个一个减的时候,会出现当前数目为偶数或者三的倍数的情况,此时采用操作1、2会比接着一个一个减更优
那么就得到了贪心策略:如果当前不满足操作1、2条件,就减去1~2个橘子分别变为偶数、3的倍数执行操作1、2
也就是说每个局面有两种选择
朴素暴搜->重复状态->记忆化搜索
操作1有log中状态,操作2有log种状态,二者组合->log^2 n 种状态,时空复杂度就确定了
2、复杂度
时间复杂度:O(log^2 n) 空间复杂度:O(log^2 n)
3、代码详解
python3
class Solution:
def minDays(self, n: int) -> int:
@cache
def dfs(x: int) -> int:
if x <= 1:
return x
return min(dfs(x // 2) + x % 2, dfs(x // 3) + x % 3) + 1
return dfs(n)
cpp
unordered_map<int, int> memo;
int dfs(int x) {
if(x <= 1) return x;
if (memo.count(x)) return memo[x];
return memo[x] = min(dfs(x / 2) + x % 2, dfs(x / 3) + x % 3) + 1;
}
class Solution {
public:
int minDays(int n) {
return dfs(n);
}
};