不准访问
- 积分
- 546
- 大米
- 颗
- 鳄梨
- 个
- 水井
- 尺
- 蓝莓
- 颗
- 萝卜
- 根
- 小米
- 粒
- 学分
- 个
- 注册时间
- 2020-11-18
- 最后登录
- 1970-1-1
|
2、贪心策略+记忆化
我们再次观察一下,当 n > 0,
1)假如路径全是由 -1 组成的 => 这种情况下到 0 的距离为 n
2)假如某条路径不只是由 -1 组成的,经过了 k 次 -1 然后出现了 /3。此时 (n-k) 一定是 3 的倍数。这条路径从 n 到 (n-k)/3 经过了 (k+1) 条边。我们证明以下结论: 如果 k >= 3,那么这条路径一定不是最优的。 可以替换为路径:我们先进行 (k-3) 次 -1,再进行 1 次 /3,再进行 1 次 -1,同样得到 (n-k)/3。但是只用了 (k-1) 条边。 于是如果最优路径是 -1 再 /3,那么 -1 的次数必然 < 3: 当 n % 3 == 0 时,k 可以为 0,3,6,9,... 我们只用考虑 k == 0 的路径 当 n % 3 == 1 时,k 可以为 1,4,7,10,... 我们只用考虑 k == 1 的路径 当 n % 3 == 2 时,k 可以为 2,5,8,11,... 我们只用考虑 k == 2 的路径
3)同理 2,假如某条路径不只是由 -1 组成的,经过了 k 次 -1 然后出现了 /2。 此时 (n-k) 一定是 2 的倍数。这条路径从 n 到 (n-k)/2 经过了 (k+1) 条边。我们证明以下结论: 如果 k >= 2,那么这条路径一定不是最优的。 可以替换为路径:我们先进行 (k-2) 次 -1,再进行 1 次 /2',再进行 1 次 -1,同样得到 (n-k)/2。 但是只用了 k 条边。 于是如果最优路径是 -1 再 /2,那么 '-1' 的次数必然 < 2。 当 n % 2 == 0 时,k 可以为 0,2,4,6,... 我们只用考虑 k == 0 的路径 当 n % 2 == 1 时,k 可以为 1,3,5,7,... 我们只用考虑 k == 1 的路径
所以,以上的结论可以辅助我们做出一个决定,一个个吃必然没有2个、3个吃更加有效。转移方程就变为$f(n) = 1+min(f(n/2)+n%2, f(n/3)+n%3)$
- class Solution {
- public:
- map<int,int>mp;
- int dfs(int i){
- if(i==0)return 0;
- if(i==1)return 1;
- if(mp.count(i))return mp[i];
- return mp[i]=min(dfs(i/2)+i%2+1,dfs(i/3)+i%3+1);
- }
- int minDays(int n) {
- mp.clear();
- return dfs(n);
- }
- };
复制代码
为什么要加上记忆化呢?没有加上记忆化的结构如下,少了很多重复递归的节点,直接map就可以完成。
而加上了记忆化的结构如下:
复杂度分析:
时间复杂度为$T(n)=T(n/2)+T(n/3)+O(1)$,加上记忆化,深度为$log(n)$,于是要遍历的节点数为$O(log^2n)$
空间复杂度:$O(log^2 n)$,即为需要存储的 $f(i)$ 的个数。
|
|