一、题目内容

二、题目分析

这道题目讲道理,我看到的第一眼就是动态规划,但是后来提交之后,发现还有大佬考虑用数学分析得出精简解法,在这里我也会一 一阐述。

对于动态规划而言,按照老套路,首先定义dp数组,含义明了,定义长度为n+1的dp数组,其中dp[i]代表长度为i的绳子的最大乘积

其次,我们寻找初始条件,简单分析就可以得到,dp[2]=1,dp[1]=1(虽然题目告诉我们n>=2,但是设置dp[1]有利于接下来的计算),好的我们得到了初始条件。

接着我们需要考虑状态转移方程,对于本题而言,这里是最困难的部分。怎么把dp[i]和dp[i-1]联系在一起呢?我们发现这是不可能的,为什么?

因为我们容易知道dp[3]等于2,是指将长度为3的绳子分成1和2或者2和1,相当于将长度为3的绳子从中间切了一刀,而dp[4]的值应该是2,是将长度为4的绳子分成两个长度为2的绳子。那么大家想一想,我怎么可以从dp[3]得到dp[4]呢?总不能把dp[3]切开的部分粘合起来吧?所以,如果用dp[3]计算dp[4],得到的结果应该是1*2*1,也就是dp[3]*(4-3),它的意思是,当长度为3的绳子分成1和2之后,又来了一个长度为1的绳子,没办法,总不能把你们拼接起来,那只能分成三份了1*2*1,得到2,由此我们可以看出,虽然通过dp[i-1]得到了一个dp[i],但是它远不是最优解

那么咋办呢?我们可以想到,既然dp[i-1]得到的不是最优解,那么总有方式得到最优解吧。

所以,我们可以在定义i从3到n的大循环内,再定义一个从0到i(左闭右开)的小循环,目的就是将dp[i-j]看成一个整体,将j看做一个整体,这样就是计算两段绳子的乘积最大值,举个例子:

dp[2]等于1,是指将长度为2的绳子分成了1和1,而dp[3]呢?我们从0开始,依次计算dp[i-j]*j,当j=0时,dp[i-j]*j=0;当j=1时,dp[i-j]*j=1,指的是将长度为2,分成1和1的那段绳子看做一个整体,然后多出来的1又做一个整体,这样得出dp[3]=1,不是最优解,么儿关系,继续看;当j=2的时候,dp[i-j]*j=2,指的是将长度为1的绳子看做一个整体,然后多出来的长度为2的绳子又看做一个整体,这里注意,这时候,不要一直关注于刚刚所说的将dp[2]分为1和1,此时是dp[1],只有一个长度为1的绳子,然后多出来的是长度为2的一个长绳子,这样就的出来最优值dp[3]=2了。

但是其实还有个问题,应该dp[i]=dp[i-j]*j并不能包含所有情况,比如dp[4]你会发现,不管怎么遍历,都只能得出3,这是因为当我们让dp[4]=dp[4-2]*2时,发现结果为1*2,,而不是我们想象的2*2,这是因为呀,dp[2]是将长度为2 的绳子分成了1和1,那么dp[4]就是将长度为4的绳子分为了1*1*2,自然不是最优解啦,这里不是最优解的根源在于,明明分成两段就可以解决的事,非要分成三段,那我们不如再考虑一下所有分成两份的情况,也就是(i-j)*j,即将所有长度为i的绳子,j从0到i,都分成(i-j)和j的绳子,这样就可以解决那种只要分成两份,而不会分成三份的情况啦。

所以最终我们的状态转移方程就是:

dp[i]=max(dp[i],dp[i-j]*j,(i-j)*j);

所以完整代码为:

 public int cuttingRope(int n) {int []dp=new int [n+1];dp[1]=1;dp[2]=1;for(int i=3;i<=n;i++){for(int j=0;j<i;j++){int tmpmax=Math.max(dp[i-j]*j,(i-j)*j);dp[i]=Math.max(dp[i],tmpmax);}}return dp[n];}

三、数学分析

这道题归类在数学题中,说明可以经过独到的数学分析得出最优的结果。

力扣上的解析讲的很好,我就不班门弄斧了:数学分析解决剪绳子问题

—— END SUB

剑指 Offer 14.剪绳子(动态规划、数学分析)相关推荐

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

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

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

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

  3. 剑指Offer:剪绳子(动态规划、贪婪算法)

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

  4. 88. Leetcode 剑指 Offer 14- I. 剪绳子 (动态规划-基础题)

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

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

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

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

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

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

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

  8. 【剑指Offer】剪绳子问题——四种解法

    剪绳子问题--四种解法 题目描述: 输入描述: 返回值描述: 示例1: 解题思路: 方法1:暴力递归 方法2:记忆化递归 方法三:动态规划 方法四,数学原理 题目描述: 给你一根长度为n的绳子,请把绳 ...

  9. 剑指offer:剪绳子(找规律,贪心算法,动态规划)

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

最新文章

  1. 【机器学习】逻辑回归(Logistic Regression)
  2. ubuntu java开发环境搭建(jdk+tomcat+eclipse)
  3. 社区团购平台得推社区团购系统 v3.1源码
  4. java怎样调用图像做按钮_swing-Java:使用图像作为按钮
  5. java安全管理器视频_安全管理器 (Security Manager)
  6. 台达PLC开发笔记(一):台达PLC连接介绍,分别使用485、网口与台达PLC建立连接
  7. 计算机网络设计大赛总结,大学生海报设计大赛总结
  8. android studio开始暂停按钮
  9. 微博、微信,媒体选择何去何从
  10. phalcon mysql_Phalcon 数据库操作总结
  11. 串联四足机器人基础知识
  12. 对List集合属性进行模糊查找
  13. The Evils of Duplication
  14. 这是一个基于Threejs的商品VR展示系统的 VR模型展示Demo
  15. 金融核心业务流程整理
  16. AXI(Advanced eXtensible Interface)协议规范
  17. java基础应用程序超市收银_超市收银程序(JAVA课程设计 2011)
  18. C++中的string用法
  19. java常见的5个异常_java常见的5种异常举例
  20. 天主教七宗罪(你范了那些条)

热门文章

  1. Bing翻译实例(microsoft translator API)
  2. 分布式系统架构系列讲解八(分布式一致性 8):PBFT算法
  3. gitlab设置中文或者其他语言,gitlab汉化
  4. 二叉树的前序遍历(Java)
  5. GDAL C++ API 学习之路 (1)Driver篇 代码示例 翻译 自学
  6. python测试框架nose研究
  7. pasa查看mysql_PASA的安装与使用
  8. 大数据实战二十四课 - Spark SQL04
  9. IBM OMNIBUS INSTALL
  10. pandas中使用fillna函数填充NaN值