• 剑指offer


    减绳子

    问题描述:

    给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段(m、n 都是整数,n>1 并且 m>1),每段绳子的长度记为 k[0],k[1],...,k[m]。请问 k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是 8 时,我们把它剪成长度分别为 2、3、3 的三段,此时得到的最大乘积是 18。

    输入描述: 输入一个数 n,意义见题面。(2 <= n <= 60)

    输出描述: 输出答案。

    输入: 8

    输出: 18
    方法一:数学公式法(贪婪算法)

    解题思路:

    绳子长度为 n,分成 m 份,

    假设每份长度为 x,那么 m=n/x;

    那么结果就是 f(x)=x^(n/x)
    剪绳子
    所以问题就回到了 n/3 的个数上面

    当 n 能被 3 整除的时候,乘积=n^(n/3)

    当 n 除 3 余 1 的时候,这时候发现多了一个 1,这个 1 是不是很鸡肋,但是把前面的一个 3 拿出来,把这个一个 1 和前面一个 3 分解为 2 和 2,就变大了,所以乘积为 3^(n/3 - 1) * 4

    当 n 除 3 余 2 的时候,乘积为 n^(n/3) * 2

    function cutRope(number) {
      // write code here
      if (number <= 1) return 0;
      if (number === 2) return 1;
      if (number === 3) return 2;
      var m = number % 3;
      switch (m) {
        case 0:
          return Math.pow(3, number / 3);
        case 1:
          return Math.pow(3, parseInt(number / 3) - 1) * 4;
        case 2:
          return Math.pow(3, parseInt(number / 3)) * 2;
      }
    }
    

    方法二:动态规划 DP

    function cutRope(number) {
      // write code here
      if (number <= 1) return 0;
      if (number === 2) return 1;
      if (number === 3) return 2;
      var arr = [0, 1, 2, 3];
      for (let i = 4; i <= number; i++) {
        var max = 0;
        for (let j = 1; j <= parseInt(number / 2); j++) {
          var max = 0;
          max = Math.max(arr[j] * arr[i - j], max);
          arr.push(max);
        }
      }
      return arr[arr.length - 1];
    }
    
  • 相关阅读:
    select_tag in rails about selected not change and onchange()
    debian7 请把标有“Debian GNU/Linux 7.1.0 _Wheezy_
    rails关于utf8问题-------------------utf8申明必须置顶
    ruby 删除文件
    svn conflict
    40亿个有序不同的数的文件中找一个缺失的数
    马云语录
    语音识别概率问题,一段在数学之美了看到的话
    两个有序数组的中位数
    磁盘文件排序-编程珠玑
  • 原文地址:https://www.cnblogs.com/muzidaitou/p/12727622.html
Copyright © 2020-2023  润新知