当前位置: 代码迷 >> 综合 >> 吃掉 N 个橘子的最少天数(emmm)
  详细解决方案

吃掉 N 个橘子的最少天数(emmm)

热度:41   发布时间:2023-12-14 14:43:11.0

 

这道题看起来很简单,我一眼就看出来可以用动态规划去做了,然后我就:

        for(int i=1; i<=n; i++){if(i % 2 == 0 && i % 3 == 0){dp[i] = Math.min(Math.min(dp[i-1]+1, dp[i/2]+1), Math.min(dp[i-1] + 1, dp[i-2*(i/3)]+1));}else if(i % 3 == 0 && i % 2 != 0) {dp[i] = Math.min(dp[i-1] + 1, dp[i-2*(i/3)]+1);}else if(i % 2 == 0 && i % 3 != 0){dp[i] = Math.min(dp[i-1]+1, dp[i/2]+1);}else {dp[i] = dp[i-1] + 1;}}

结果,当n的值为61455274时,数组太大,栈溢出?

然后我就想,既然从下向上做栈溢出,那我从上往下做总可以了吧,采用递归get函数:

  • 比如说是n = 11:
  • 11既不能被2整除,也不能被3整除,所以只能是get(10)+1步
  • 10进来了,能被2整除,不过get不一定是get(5)+1就小,因为结果证明,get(9)+1的结果会更小,所以Min{get(5)+1, get(9)+1}
  • 然后就去找get(5)和get(9)
  • 比如9,因为我们也无法确定是get(3)+1大还是get(8)+1大,所以我又去判断了get(8)
  • ......

从上到下,每个元素都判断了一遍,结果大大超时!!!

然后我咋想就想不出来到底该咋办,唉.............看了答案:

class Solution {public int minDays(int n) {return getMinDay(n);}private Map<Integer, Integer> maps = new HashMap<>();private int getMinDay(int n){if(n == 1) return 1;if(n == 2) return 2;if(n == 3) return 2;Integer re = maps.get(n);// 是否之前计算过if(re != null) return (int)re;int m2 = getMinDay(n/2)+n%2;int m3 = getMinDay(n/3)+n%3;int result = Math.min(m2, m3)+1;// 存储结果maps.put(n,result);return result;}
}

就这三步操作,你细品吧:

        int m2 = getMinDay(n/2)+n%2;
        int m3 = getMinDay(n/3)+n%3;
        int result = Math.min(m2, m3)+1;