python 实现 割绳子问题(剑指offer 14题) 动态规划 或者贪心算法

2,888 阅读2分钟

一直挺苦恼动态规划笔试、面试题目,今天开始稳扎稳打的思考解决问题。

如题:给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],...,k[m].

请问k[0]k[1]...*k[m]可能的最大乘积是多少?

例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积是18.

通常动态规划的问题都是求最优解,即最大或最小值或者最优组合等。这类问题都是可以从一个大问题分解为一个小问题,小问题也存在求解最优的情况。例如,绳子假如被割为N段,要达到N段绳子长度成绩最大,这个N段的子集都要求为最优情况。所以这就是一个典型的动态规划问题。

先找规律,如果绳子长度为0,那么最优为0,如果为1,那么为一,如果为2,那么还是为2,如果为3,那么为2(由于n,m>1所以长度为2时,不能割。当长度为3时,必须割一刀,所以1X2还是2) 不用递归用列表就可以实现,试想将绳子从0~N的长度的最优解存在List里面,然后每次割(不论从哪里割,都会降为两个列表内子集的最优解问题这样就可以解决了。就是说如果绳子长为5,那么5可以有很多种割法(1,4)(2,3),而1,2,3,4怎么割的最优解都在List里,然后pick max value这个问题就得以解决了。)

具体实现代码如下

从头开始找规律再想想好像还有别的方法,有没有这样一种最小最优因子,如果将N长的绳子全部由他或者最多由他组成,那么问题也就解决了。贪心的意思也就是在这里,我要每段最优,然后组成整体最优。

例如2不能割,3最优分割为3>1X2,4被分割最优为4=2X2,5被分割最优为2x3,6为3X3,我有一个大胆的想法,保证3的个数如果有1为余数那就减少一个3用来凑成4=2X2(保证不比割前小即可)这样问题好像还真的就得到了解决。因为2(n-2)与3(n-3)只有在5的时候是相等的,当n大于5的时候3(n-3)是最优的。

贪心算法貌似更简单~