减绳子

image.png
看到题目首先觉得是递归算法-动态规划 Dynamic Programming--从菜鸟到老鸟

题目分析

本题目就是分析k0k1……*km的最大值
根据数学公式
image.png
简单来说就是需要比较axb和((a+b)/2) x ((a+b)/2)的大小,a*b的最大值就是((a+b)/2) x ((a+b)/2),当且仅当a=b时成立,所以原题目就是当里面的n1 n2 na全部相等式等号成立,也就是均分
按照题目通过计算找到极值点发现是e,但是题目要求必须为整数,也就是2或者3,然后通过计算发现整数取3的时候可以得到最大值,乘积最大。
image.png

切分规则 找规律

  • 把绳子尽可能的切成多个长度时3的,最后留下的最后一段绳子应该长度时0 1 2
  • 如果最后一段的绳子长度是2,就不剪了,因为2>1*1
  • 如果最后一段的绳子长度是1,就应该把倒数第二段的3合起来,变成4然后拆成2+2,因为22>13,此时前面都是全部是3的绳子段子,只是最后两段变了
  • image.png

题解

image.png

牛批写法:和三为一:return n <= 3? n - 1 : pow(3, n / 3) * 4 / (4 - n % 3);

这个合三为1真的是很强了
image.png
这个是以4为临界点,因为4除3余1,所以遇到最后分割剩下4就跳出循环然后直接×剩下的4,如果不是4,是5,那就剩下2,继续运算就好了

递归算法 没找到规律的话

  • 基本思路:采用动态规划方法。定义dp状态result[i]为绳长为i时,绳子的可能最大长度乘积。下面我们探究递推关系,对于绳长为i的绳子,我们选择在j位置将绳子剪断,此时绳子被分成长度为j和长度为i - j的两部分,此时剪断之后绳子可能的最大长度乘积,为绳长为j和绳长i - j时候结果的积。而dp状态更新为max(result[i],result[j] × result[i - j])。
  • 其实就是定义绳子得到的最大乘积状态:dp状态result[i]为绳长为i时,绳子的可能最大长度乘积
  • 然后将i此时得到的最大乘积值存到数组里,然后将i继续裁剪又可以将i的绳子分为j和i-j,那么此时绳子的最大乘积为j*(i-j),也就是此时dp状态result[i]的最大乘积应该是max(result[i],result[j] × result[i - j]),万一剪开之后乘积不如原来的大呢,所以就得利用max找到最大的
  • dp数组的长度:由于定义result[i]为绳长度为i时的结果,因此result[n]为最后一项,所以数组的总长度为n + 1
  • j的遍历范围:如果j > i/2,那么result[j]已经由之前的result[i - j]遍历过,导致重复计算,因此j最多遍历到i/2。同时,由于题目规定必须要切一刀,因此不能使得某一段的长度为0,因此j最少遍历到1。
  • 当作为结果返回时,必须要切一段,不能不切。但是如果不是递归调用就可以不用切

image.png
image.png


Loccy
4 声望1 粉丝