LeetCode-LCS 01. 下载插件

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode-LCS 01. 下载插件相关的知识,希望对你有一定的参考价值。

题目描述

小扣打算给自己的 VS code 安装使用插件,初始状态下带宽每分钟可以完成 1 个插件的下载。假定每分钟选择以下两种策略之一:

  • 使用当前带宽下载插件
  • 将带宽加倍(下载插件数量随之加倍)

请返回小扣完成下载 n 个插件最少需要多少分钟。

注意:实际的下载的插件数量可以超过 n 个

示例

输入:n = 4
输出:3
解释:
最少需要 3 分钟可完成 4 个插件的下载,以下是其中一种方案:
第一分钟带宽加倍,带宽可每分钟下载 2 个插件;
第二分钟下载 2 个插件;
第三分钟下载 2 个插件。

贪心选择

贪心算法:判断当前下载量1分钟是否可以搞定,如果可以就不需要加倍,反之加倍便是最优选择。

class Solution {
    public int leastMinutes(int n) {
      int res = 0;
      int cur = 1;
      while (n > 0) {
          if (n <= cur) {
              n -= cur;
          } else {
              cur <<= 1;
          }
          res++;
      }
      return res;
    }
}

回溯算法

每步可以选当前数和不选当前数(加倍)

算法超时

class Solution {
    int ans = Integer.MAX_VALUE;
    public int leastMinutes(int n) {
        backTrack(n, 0, 0, 1);
        return ans;
    }
    public void backTrack(int n, long cur, int idx, long cnt) {
        if (idx >= ans)  // 剪枝操作
            return;
        if (cur >= n) {
            ans = (ans > idx) ? idx: ans;
            return;
        }
        if (cnt > Integer.MAX_VALUE)
            return;
        backTrack(n, cur+cnt, idx+1, cnt);
        backTrack(n, cur, idx+1, cnt*2);
    }
}

动态规划

令 dp[i] 表示下载 i 个插件需要的最少分钟数,则 dp[i] = dp[(i + 1) / 2] + 1;

状态转移方程dp[i] = dp[(i + 1) / 2] + 1;

等同于第四种数学方法,优先加倍宽带,那个+1就代表只用1天来完成,以10为例,dp【10】=dp【5】+1,dp【5】=dp【3】+1。。。dp【2】=dp【1】+1为止.

class Solution {
    public int leastMinutes(int n) {
       // dp[i] 表示下载 i 个插件需要的最少分钟数
       int[] dp = new int[n+1];
       dp[1] = 1;
       for (int i = 2; i <= n; i++) {
           dp[i] = dp[(i+1)/2]+1;
       }
       return dp[n];
    }
}

数学

一直加倍到大于等于目标值,这时进行一次使用带宽下载即可。

class Solution {
    public int leastMinutes(int n) {
        return (int)(Math.ceil(Math.log(n)/Math.log(2)) + 1);
    }
}

以上是关于LeetCode-LCS 01. 下载插件的主要内容,如果未能解决你的问题,请参考以下文章

VIM 代码片段插件 ultisnips 使用教程

从零开始配置vim(27)——代码片段

从零开始配置vim(27)——代码片段

从零开始配置vim(27)——代码片段

#VSCode保存插件配置并使用 gist 管理代码片段

VSCode插件开发全攻略代码片段设置自定义欢迎页