问题描述

给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],…,k[m]。请问k[0]xk[1]x…xk[m]可能的最大乘积是多少?

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

输入描述:
输入一个数n,意义见题面。(2 <= n <= 60)
输出描述:
输出答案。

示例1
输入 8
输出 18

解题思路

本题有几个 可使用动态规划算法的明显特征
(1)是求最优解问题,如最大值,最小值;
(2)该问题能够分解成若干个子问题,并且子问题之间有重叠的更小子问题。

通常按照如下 4 个步骤来 设计一个动态规划算法
(1)刻画一个最优解的结构特征;
(2)递归地定义最优解的值;
(3)计算最优解的值,通常采用自底向上的方法;
(4)利用计算出的信息构造一个最优解。

以此题为例,

设长度为 n 的绳子剪切后的最大乘积为 f(n),

我们可以将问题看成两个子问题,即 f(n) = max(f(j)*f(n-j)) ,j 属于 (1, 2, …, n/2)

也就是说,我们要求 f(n),就只要求将 n 分成 n 、n-j 里面的最优分解就行了。

为什么 j 的边界是 n/2 呢? --> 因为将一个数分成两个数,最大的就是 n/2

**假设 n 为 11,**第一刀之后分为了 4-7,而 7 也可能再分成 1-5(7 的最大是 3-4,但过程中还是要比较 1-5 这种情况的),而上一步 4-7 中也需要求长度为 4 的问题的最大值。

可见,各个子问题之间是有重叠的,所以可以先计算小问题,存储下每个小问题的结果,逐步往上,求得大问题的最优解。

Java 代码(动态规划)

import java.lang.*;public class Solution {public int cutRope(int target) {if (target < 2) {return 0;}if (target == 2) {return 1;}if (target == 3) {return 2;}// ropes[i]表示剪i次时的最大乘积int[] ropes = new int[target + 1];ropes[1] = 1;ropes[2] = 2;ropes[3] = 3;int temp = 0;for (int i = 4; i <= target; i++) {int max = 0;// f(i) = max(f(j)*f(n-j)), j属于(1,2,...,n/2)for (int j = 1; j <= i / 2; j++) {temp = ropes[j] * ropes[i - j];max = Math.max(temp, max);}ropes[i] = max;}return ropes[target];}
}

复杂度分析:

  • 时间复杂度:O(n^2)。
  • 空间复杂度:O(n)。

Java 代码(贪婪算法)

另解(使用贪婪算法):

当 n<5 时,与动态规划的处理一致;

当n>=5时,尽可能多地剪长度为 3 的绳子,当剩下的绳子长度为 4 时,剪成 2-2;

例如:长度为 10 的绳子, 剪成 3-3-2-2

public int maxProductAfterCutting(int length) {if (length < 2) {return 0;}if (length == 2) {return 1;}if (length == 3) {return 2;}// 尽可能多地剪去长度为3的绳子段int timesOf3 = length / 3;// 当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段// 此时更好的方法是把绳子剪成长度为2的两段,因为2x2>3x1if (length - timesOf3 * 3 == 1) {timesOf3 -= 1;}int timesOf2 = (length - timesOf3 * 3) / 2;return (int) (Math.pow(3, timesOf3) * Math.pow(2, timesOf2));
}

复杂度分析:

  • 时间复杂度:O(1)。
  • 空间复杂度:O(1)。

虽然贪婪算法的时间复杂度低,但面试官一般都会要求证明

数学证明:

https://www.jianshu.com/p/0a13e48aa4af

剑指Offer:剪绳子(动态规划、贪婪算法)相关推荐

  1. python剑指offer剪绳子

    题目 给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],-,k[m].请问k[0]k[1]-*k[m]可能的最大乘积是多少 ...

  2. 【剑指offer】剪绳子(动态规划)

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

  3. 《剑指offer》c++版本 14.剪绳子

    本题在牛客网剑指offer专项里没看到,原书第二版上有,如题: 这道题是开放的动态规划题,题目中只给了绳子长度,却没定义具体剪多少段,初遇此题,难以下手,看了题解,豁然开朗.设f(n)为常为n的绳子剪 ...

  4. 剑指Offer 14- I. 剪绳子(Medium)/ 剪绳子 II(Medium)/ 343. 整数拆分(Medium)

    剑指Offer 14- II. 剪绳子 II(Medium) 343. 整数拆分(Medium) [题目连接] 题解 剪绳子(数学推导 / 贪心思想,清晰图解) 图解[暴力递归][记忆化技术][动态规 ...

  5. 【LeetCode】剑指 Offer 14. 剪绳子

    [LeetCode]剑指 Offer 14. 剪绳子 文章目录 [LeetCode]剑指 Offer 14. 剪绳子 两道题目的区别在于第二题 n 的取值范围更大 package offer;publ ...

  6. 【LeetCode】【剑指offer】【剪绳子(二)】

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

  7. 剑指 Offer 14- II. 剪绳子 II

    剑指 Offer 14- II. 剪绳子 II 题目描述 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[ ...

  8. 【算法-剑指 Offer】62. 圆圈中最后剩下的数字(环形链表;约瑟夫环;动态规划)

    剑指 Offer 62. 圆圈中最后剩下的数字 - 力扣(LeetCode) 发布:2021年9月12日12:18:52 问题描述及示例 0,1,···,n-1这n个数字排成一个圆圈,从数字0开始,每 ...

  9. 剑指 Offer 46. 把数字翻译成字符串(动态规划+回溯+递归 解法)

    剑指 Offer 46. 把数字翻译成字符串 问题描述 给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 "a" ,1 翻译成 "b",--,11 翻 ...

  10. 剑指 Offer 60. n个骰子的点数(动态规划)

    [剑指 Offer 60. n个骰子的点数] 思路: \qquad题目其实不难,写这篇博客主要是记录下C++使用vector开多维数组. \qquad思路类似于走台阶,每次可以走1,2,3阶,问到每一 ...

最新文章

  1. 16S+功能预测也能发Sciences:尸体降解过程中的微生物组
  2. 安卓WebView加载网页不显示或者乱跳问题
  3. java Date获取 年月日时分秒
  4. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】
  5. 利用Eigen进行矩阵计算
  6. mysql jdbc 表结构_JDBC操作表:JDBC修改表结构
  7. Qt实践录:串口调试助手
  8. 关于打印数组一直输出地址符号的一个解决方法
  9. redis多服务器共享_基于redis和shedlock实现分布式锁(超简单)
  10. php 检验类,php实现的简单检验登陆类
  11. 【Python数据分析】数据挖掘建模——分类与预测——决策树
  12. 本地html图片载入很慢,打开网页时图片加载很慢怎么办?网页图片打开慢的解决方法...
  13. HDU—校赛—1004
  14. ping检测整个网段地址在线
  15. icp相关数学,向量模的平方转换成矩阵相乘
  16. CSDN如何转载别人的博客
  17. Apache Kudu架构
  18. App推广干货:一个新的App该如何推广
  19. Rust腐蚀盒子小程序抄家工具上线
  20. 安装mysql odbc重启mssql_关于php连接mssql:pdo odbc sql server

热门文章

  1. 扫掠两条引导线_如何巧用引导线,把摄影水平再提升一个档次?
  2. VMware ESXI虚拟化安装win10系统
  3. [SOSP 17] Wukong+S : 不断演化的RDF数据的亚毫秒级别的状态流查询
  4. android 6gb和8gb区别,手机6GB内存和8GB内存的差距到底有多大?你可能被忽悠了!...
  5. hdu1042 java_hdu 1431 素数回文
  6. ubuntu python3.5安装_ubuntu16.04升级Python3.5到Python3.7的方法步骤
  7. 自动化监控--zabbix中的用户和用户组详解
  8. Win2008 R2 WEB 服务器安全设置指南之修改3389端口与更新补丁
  9. 处理get中的中文乱码情况
  10. 代码大全阅读笔记02