题目

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

题目解析

首先题目描述并不是很清楚,我看了一下,比较准确的描述是,绳子分成m个部分,也就是m段。
默认的条件是

  • 绳子不能不被分割,也就是至少被分为两个部分
  • m、n都是整数,n>1并且m>1(也就是说长度至少为2,而且分割为至少两段)
  • 不同部分绳子的长度都为整数,长度记录为k[0],k[1],…,k[m-1]

目的

  • 在不同切分方法中,找到最大乘积 k[0]×k[1]×…×k[m-1]。

方法解析

本题可以用贪婪算法和动态规划算法求解,虽然贪婪算法的时间复杂度和空间复杂度都比动态规划算法要小,但是要求有一定数学基础,需要定制合理的贪婪策略(面试的时候如果换一道题一般情况下想不出来的)。
一般来说贪婪算法在本题中没有参考价值,最好还是用动态规划的方法来求解。

动态规划

动态规划求解问题的四个特点:

  1. 求一个问题的最优解.
  2. 整体问题的最优解依赖于各个子问题的最优解.
  3. 我们把大问题分解成若干个子问题,这些小问题之间还有相互重叠的更小的子问题.
  4. 用从上往下的顺序先计算小问题的最优解,并存储下来,再以此为基础求取大问题的最优解.

通常按照4个步骤设计一个动态规划算法:

  1. 刻画一个最优解的结构特征(也就是这个最优解怎么描述,有哪些决定的属性呢?)
  2. 递归地定义最优解的值(大问题的最优解是依赖于小问题的最优解的,整体问题的最优解依赖于各个子问题的最优解.).
  3. 计算最优解的值,通常采用自底向上的方法.
  4. 利用计算出的信息构造出一个最优解.

动态规划方法仔细安排求解顺序,对每个子问题只求解一次,并将结果保留下来.

动态规划

假设f(n)为长度为n的绳子剑成若干段后的最大乘积。
那么如果我们只剪一刀,该绳子就会分为两部分,假设在i上剪断,我们再求出这两部分绳子的最大乘积f(i),f(n-i)。(f中的参数代表长度,在不同的i上进行切分的话,会有多种方案)
然后不断以相同的方式进行分割,可以得到f(n)=max(f(i)*f(n-i))。 //也就是一次剪掉一个

这是从上至下的递归公式,我们通常采用的是自下而上的解法.

  • 当绳子长度为2时,只可能剪成长度为1的两段,所以f(2)=1
  • 当绳子的长度为3时,可能把绳子剪成长度为1,1,1或1,2,因为12>11*1,所以f(3)=2;

用动态规划自下而上的计算,先算出n为1、2、3的最大乘积,知道小的以后在去算更大的乘积。比如n为4时候最大的可能只能在1*3
这道题目的临界点其实是4,也就是说4以下的其实不论怎么分,成绩都不可能比自身的数大!那么此时存储的其实是最大的值,不一定是乘法最大值。
所以在下面的代码中,fun[1]=1;fun[2]=2;fun[3]=3;其中存放的其实是不切的最优解,这几个数字是比较特殊的。

class Solution {public:int cutRope(int number) {//因为至少要分为两段(m>1),所以先排除几个f(n)<n的特例int len=number;if(len<2)return 0;if(len==2)return 1;if(len==3)return 2;// int max=0;//存储当前最大的fun(n)int *fun = new int[len+1];memset(fun,0,sizeof(*fun)*(len+1));fun[0]=0;fun[1]=1;fun[2]=2;fun[3]=3; //f[3] 如果二分结果并不是3 而是2最好的分法是不分, f[3] = 3for(int i=4;i<=len;i++) //绳子的长度是从小到大变化的{for(int j=1;j<=i/2;j++) //绳子只需要剪前一半的就可以,剪i和剪n-i一样的{//fun[0],fun[1],...,fun[i-1]都是之前已经计算过了,接下来我们就找出两个乘积最大的fun[i] = max(fun[j]*fun[i-j],fun[i]);//从某个长度的多种分割方案中找到乘积最大的}}return fun[len];}
};

贪心法

当n<=3时,不再进行剪切,因为会比n小。
当n==4时,将n=2*2,因为只有两种剪法,剪成1,3比较小。
当n>=5时,我们要把所有的绳子都剪成2或者3,同时我们要尽可能的多剪长度为3的绳子,因为3(n-3)>=2(n-2),当剩余的小于5时就没有必要再剪。
简要来说,尽可能分3,不足的就分2。当剩下的绳子长度为4时,把绳子剪成长度为2的绳子。

class Solution {public:int cutRope(int number) {int max=1;if(number<=3 && number>0){return number-1;}while(number>4) //减到剩4就可以了{number-=3;max*=3;}return max*number;}
};

参考资料

剪绳子——剑指offer——动态规划
算法之动态规划(剑指offer-剪绳子详解)
剑指offer:剪绳子

动态规划-剪绳子问题相关推荐

  1. 剑指offer【14】动态规划 剪绳子

    def maxProductAfterCutting_solution(length):if length <2: #因为要求至少剪成两段return -1if length ==2:retur ...

  2. 【LeetCode笔记】剑指 Offer 14. 剪绳子 I II(Java、动态规划、偏数学)

    文章目录 剪绳子 I 题目描述 思路 && 代码 1. 动态规划 O(n2n^2n2).O(n) 2. 最优解:数学方法 O(n).O(1) 二刷 剪绳子 II 题目描述 思路 &am ...

  3. 剪绳子 算法_[校招-算法题]动态规划

    动态规划(Dynamic Programming)是面试中非常常见的一种算法,可以解决很多复杂问题. 核心算法: 定义状态:dp[i],一个数组,具体几维根据问题定. 状态转移方程:dp[i] = b ...

  4. 剑指 Offer 14.剪绳子(动态规划、数学分析)

    一.题目内容 二.题目分析 这道题目讲道理,我看到的第一眼就是动态规划,但是后来提交之后,发现还有大佬考虑用数学分析得出精简解法,在这里我也会一 一阐述. 对于动态规划而言,按照老套路,首先定义dp数 ...

  5. 【算法】【动态规划篇】第5节:剪绳子问题

    本期任务:介绍算法中关于动态规划思想的几个经典问题 [算法][动态规划篇]第1节:0-1背包问题 [算法][动态规划篇]第2节:数字矩阵问题 [算法][动态规划篇]第3节:数字三角形问题 [算法][动 ...

  6. 剪绳子(动态规划和贪婪算法)

    题目: 把长度为n的绳子剪成m段(n>1,m>1),每段绳子的长度记为k[1],...k[m],则每段绳子的长度的最大乘积是多少?例如身子长度为8时,剪成2,3,3三段得到的乘积最大,为1 ...

  7. 12、剪绳子——剑指offer——动态规划

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

  8. 动态规划贪婪算法之剪绳子

        动态规划算法是通过拆分问题,定义问题状态和状态之间的关系,使得问题能够以递推(或者说分治)的方式去解决. 1. 可以使用动态规划的情形: (1)在应用动态规划之前,要分析能否把大问题分解成小问 ...

  9. 动态规划--09-[剑]剪绳子1[中等]

    力扣 力扣 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] .请问 k[0]*k[ ...

最新文章

  1. linux 用户java_linux之用户管理
  2. 后盾网lavarel视频项目---lavarel中的tinker是什么
  3. java应用:csv文件的读写
  4. mysql的extract_mysql中json_extract函数的使用?作用是什么?
  5. Shell文件的排序、合并和分割
  6. SharePoint 2013 搜索SharePoint 特定列和特定文档(自己定义搜索)
  7. Node.js异步库async
  8. Core IO学习心得
  9. 输入法中的全角和半角是什么,角又是什么
  10. 【突发】解决remote: Support for password authentication was removed on August 13, 2021. Please use a perso
  11. linux 安装Paramiko模块安装和使用
  12. 查找算法之五 分块查找(C++版本)
  13. 空硬盘恢复linux,linux使用foremost恢复文件,硬盘恢复
  14. 解决Eth0网卡不存在的情况_wuli大世界_新浪博客
  15. iPhone苹果手机尺寸大小
  16. 刷脸自助登记 访客管理不再潦草应对!
  17. Uni-App - 接口 - 第三方登录(H5+ APP)(Hcoder 版)
  18. 可以称为是“钢铁侠” 原型
  19. Gitlab调优-备份及恢复
  20. 计算机高考英语,高考英语优秀作文 Computer(计算机)

热门文章

  1. 什么是垂直搜索引擎(之二)
  2. 安卓接入微信php处理,PHP对接微信公众号实现简单自动回复
  3. c语言餐厅点餐管理系统源码,C语言实现餐饮点餐管理系统.pdf
  4. Jackknife,Bootstraping, bagging, boosting, AdaBoosting, Rand forest 和 gradient boosting的简单介绍
  5. 微信小程序获取urlScheme地址Python版
  6. perl中grep用法总结
  7. 30岁的问题,为什么有人说程序员只能干到30岁。
  8. ubuntu20.04-cuda100-cudnn7.6.5-tensorflow-gpu2.0.0安装测试记录
  9. 【CC】| 创建三维模型教程
  10. system(“pause”)是什么