剑指offer:剪绳子

题目:
给定一根长度为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。

def cutRopeDP(length):
    """
    在剪绳子这个题目中,由于必须要剪一刀,因此会导致当所给的绳子长度是小于4的时候,剪完之后的长度
    小于剪之前的长度。但是我们在递推的时候,例如求f(5) = max{f(1)*f(4), f(2)*f(3)} = 6
    如果令f(3)=2的话,将导致递推公式错误,因此,对于小于4的输入,我们特殊处理。
    """
    if length < 2:  # 由于至少剪一刀,所以当长度小于2的时候无法剪,因此返回0
        return 0
    if length in (2, 3):
        return {2: 1, 3: 2}[length]

    products = [0, 1, 2, 3]  # 初始化长度小于4的输入所对应的输出的最大值
    for i in range(4, length + 1):
        max_product = 0
        # 对于每一个输入,我们需要遍历它所有可能的输出然后挑出最优的
        for j in range(1, i // 2 + 1):
            max_product = max(max_product, products[j] * products[i - j])
        products.append(max_product)

    return products[-1]

def cutRopeGreedy(length):
    """
    当n>=5的时候,2(n-2) > n and 3(n-3) > n; 3(n-3) >= 2(n-2)
    也就是说当长度大于5的时候,剪出长度为3的段数越多最后的乘积越大

    但是对于长度为4的时候,如果剪出一段长度为3,另一段长度为1,则乘积为3,小于剪出两段长度为2
    因此,当最后剩下4的时候,不是剪成1,3而是剪成2,2

    但是使用贪心方法求解最优解的时候需要非常tricky,因此优先尝试dp吧
    """
    if length < 2:  # 由于至少剪一刀,所以当长度小于2的时候无法剪,因此返回0
        return 0
    if length in (2, 3):
        return {2: 1, 3: 2}[length]
    timesOf3 = length // 3
    if length - timesOf3 * 3 == 1:
        timesOf3 -= 1
    timesOf2 = (length - timesOf3 * 3) // 2
    return 3 ** timesOf3 * 2 ** timesOf2

原文地址:https://blog.51cto.com/jayce1111/2381089

时间: 2024-10-09 10:14:12

剑指offer:剪绳子的相关文章

剑指OFFER 剪绳子

剑指OFFER 剪绳子 class Solution { public: int cutRope(int number) { //最少要剪一次,所以前面的dp数据有点特别 if(number == 1)return 1; if(number == 2)return 1; if(number == 3)return 2; vector<int> dp; dp.resize(number + 1); //这里是不需要再剪的数据,这里可能会多余一两个数据,但是没有关系,都写上 dp[0]=0; dp

剑指offer 面试14题

面试14题: 题目:剪绳子 题:给你一根长度为n的绳子,请把绳子剪成m段(m,n都是整数,且n>1,m>1),每段绳子的长度记为k[0],k[1],k[2],...,k[m].请问k[0]*k[1]*...*k[m]可能的最大乘积是多少?例如,当绳子的长度为8时,我们把它剪成长度分别为2,3,3的三段,此时得到的最大乘积为18. 解题思路:基于动态规划和贪婪算法,详见剑指offer P96 解题代码: # -*- coding:utf-8 -*- class Solution: def Max

【剑指offer】Q38:数字在数组中出现的次数

与折半查找是同一个模式,不同的是,在这里不在查找某个确定的值,而是查找确定值所在的上下边界. def getBounder(data, k, start, end, low_bound = False): if end < start : return -1 while start <= end: mid = ( start + end ) >> 1 if data[ mid ] > k: end = mid - 1 elif data[ mid ] < k: star

【剑指offer】树的子结构

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25907685 剑指offer第18题,九度OJ上测试通过! 题目描述: 输入两颗二叉树A,B,判断B是不是A的子结构. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行一个整数n,m(1<=n<=1000,1<=m<=1000):n代表将要输入的二叉树A的节点个数(节点从1开始计数),m代表将要输入的二叉树B的节点个数(节点从1开始计数).

【剑指offer】二叉树的镜像

转载请注明出处:http://blog.csdn.net/ns_code/article/details/25915971 题目描述: 输入一个二叉树,输出其镜像. 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<=n<=1000,n代表将要输入的二叉树节点的个数(节点从1开始编号).接下来一行有n个数字,代表第i个二叉树节点的元素的值.接下来有n行,每行有一个字母Ci.Ci='d'表示第i个节点有两子孩子,紧接着是左孩子编号和右孩子编号.C

【剑指offer】数组中仅仅出现一次的数字(1)

转载请注明出处:http://blog.csdn.net/ns_code/article/details/27649027 题目描写叙述: 一个整型数组里除了两个数字之外,其它的数字都出现了两次.请敲代码找出这两个仅仅出现一次的数字. 输入: 每一个測试案例包括两行: 第一行包括一个整数n,表示数组大小.2<=n <= 10^6. 第二行包括n个整数,表示数组元素,元素均为int. 输出: 相应每一个測试案例.输出数组中仅仅出现一次的两个数.输出的数字从小到大的顺序. 例子输入: 8 2 4

牛客网上的剑指offer题目

题目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 题目:请实现一个函数,将一个字符串中的空格替换成"%20" 两种方法实现:输入一个链表,从尾到头打印链表每个节点的值 用两个栈来实现一个队列,完成队列的Push和Pop操作. 队列中的元素为int类型. 剑指offer 斐波那契数列 一只青蛙一次可以跳上1级台阶,也可以跳上2级--它也可以跳上n级.求该青蛙跳上一个

剑指Offer——如何做好自我介绍

剑指Offer--如何做好自我介绍 前言 自我特点+经历梳理 ??各位老师好,我叫某某某,研究生三年级,就读于某某大学信息科学与工程学院软件工程专业.主要使用的开发语言是Java,熟悉基本数据结构和基本算法实现:熟悉MySQL数据库:掌握Linux基本操作命令:所参与的主要项目有"立马送药","鲜花礼品网","基于Android实现的购彩系统"和"我看看"购物分享Android APP.其中,"立马送药"的

剑指Offer——Trie树(字典树)

剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.可见,优

【剑指Offer面试题】二维数组中的查找

下决心AC所有剑指offer面试题. 九度OJ面试题地址:http://ac.jobdu.com/hhtproblems.php 书籍:何海涛--<剑指Offer:名企面试官精讲典型编程题> 对于面试题,面试官往往更希望我们能提出优化方法,这样更能体现我们的思维能力以及传说中的"内功".所以做剑指offer要着重训练这方面,多总结多细究,总是有好处的.加油~ 二维数组中的查找 时间限制:1 秒内存限制:32 兆 特殊判题:否提交:19005解决:3642 题目描述: 在一个