一、前言
《剑指Offer》中题14
二、题目
给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0] X k[1] X ... X k[m]。可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
三、思路
第一种解法:递归自顶向下解法
当第一次看到这个问题的时候第一反应的什么呢?有点蒙,再细细想想这个问题。将一根绳子分为m段其乘积最大,m段必定有两部分组成定为m1,m2,要想m段乘积最大,就需要保证m1段中的分割乘积是最大,同理m2也需一样。先看下面图,n第一次分割之后如下:
备注,第一行和下面组合不是两个值直接相乘,而是拆分之后最大的值相乘,例如 m1 长度为 6, m2 长度 n-6,m1分割最大乘积是9(3*3)
最大的结果肯定为其中一个组合,即:f(n) = max(f(i) X f(n-i));同理 f(i),f(n-i)又可以往下切割,直到最小单位位置,最小切割单位为 f(1) = 1,f(2) = 2, f(3) = 3。
分析完成脑海立马想到的是递归解法,递归简单易懂。
第二种解法:递推自下而上解法
递归很好理解,但递归重复了大量计算,随着n值增大,效率呈指数下降。递归是自顶向下,那有没有自下而上的解法呢?
回顾一下斐波那契数列第二种解法,它是每次计算f(k),f(k+1)的值,通过f(k),f(k+1)可以求出f(k+2),通过f(k+1)ÿ