文章目录

  • 题目
    • 数论
      • 思路
      • 代码
      • 复杂度分析
    • 动规一
      • 思路
      • 代码
    • 动规二
      • 思路
      • 代码
  • 对最终结果取模1e9+7
    • 思路
    • 代码

题目

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

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

提示:

2 <= n <= 58

来源:力扣(LeetCode)


数论

数学的魅力被展现的淋漓尽致~

思路

  1. 除非不得已的情况,否则不要剪成长度为1的段(1乘n等于n,对于最大乘积没有提升)。
  2. 任何大于1的数都可由2和3相加组成(根据奇偶证明)。
  3. 因为2*2=1*42*3>1*5, 所以将数字拆成2和3,能得到的积最大。(4和5还是拆分成2、3更有利)
  4. 因为2*2*2<3*3, 所以3越多积越大

代码

class Solution {public:int cuttingRope(int n) {return n <= 3? n - 1 : pow(3, n / 3) * 4 / (4 - n % 3);}
};

复杂度分析

时间复杂度:O(log(n/3))
空间复杂度:O(1)


动规一

这个版本比较好理解。

思路

  1. 每段都应该为3或者2(证明段应该为2或3不再赘述)。
  2. n=2n=3时最大乘积作为不具有规律的特殊值直接返回(因为n<=3时无法切分成3,不具有第一点所说的规律)。
  3. 动态规划数组dp中 下标为n 的位置保存着 长度为n的绳子的最大乘积(n=2,3时不再此列,已做特殊处理)。
  4. dp数组的长度:由于定义 dp[i] 为绳长度为 i 时的结果,因此 dp[n] 为最后一项,所以数组的总长度为 n + 1
  5. dp下标为1,2,3中保存的就是1,2,3,其含义是 当n>3时,3已经不用在切分了, 切成1,2的话最大乘积也就是2,不切的话得到3,比切了得到的2更大(dp[2]同理)。

代码

class Solution {public:int cuttingRope(int n) {if(3 >= n){return n-1;}vector<int> dp(n+1,0);dp[1] = 1;dp[2] = 2;dp[3] = 3;for(int i = 4; i <= n; i++){ // n > 3的处理// j<=i/2是因为1*3和3*1是一样的,没必要计算在内,只要计算到1*3和2*2就好了for(int j = 2; j <= i/2; j++){// 剪一段长度为1的绳子对乘积的提升没有作用// 因此从2开始剪dp[i] = max(dp[i], dp[j] * dp[i-j]);}}return dp[n];}
};

动规二

有一点抽象,但是不做特殊值的处理,属于力求包含所有规律的“正规”动规。

思路

  1. n=2 的值作为历史值,开始求规律。
  2. max(dp[i-j], i-j) 对于这一步可能是最难理解的,其实这只是为了处理 n=3 的特殊情况,逻辑思想是: 减去 j 后,剩余部分可以剪也可以不剪。如果不剪,则得到的长度乘积为 j * (i - j) ;如果剪,得到的长度为 j * dp[i - j] 。两者取最大值。

为什么说这只是为了处理 n=3 的特殊情况呢?
其实在数论方法中我们已经提到过了—— 因为2*2=1*4,2*3>1*5, 所以将数字拆成2和3,能得到的积最大。(4和5还是拆分成2、3更有利),也就是仅对于 2(和3) ,有 dp[2] (dp[3])小于 2(3),在 n>3 时,max(dp[i-j], i-j) 的结果是恒定的—— dp[n] > n


代码

class Solution {public:int cuttingRope(int n) {if(n == 2){return 1;}vector<int> dp(n+1);dp[2] = 1;for (int i=3; i<=n; ++i){ // n >= 3for (int j=1; j<=i/2; ++j){// j 减去的长度dp[i] = max(max(dp[i-j], i-j) * j, dp[i]);}}return dp[n];}
};

对最终结果取模1e9+7

思路

动规是用不了了,因为:

  • 计算结果可能会超出int/long范围
  • 取余之后max函数就不能用来比大小了(所有大于1e9+7的数取模后就小于1e9+7了,也就是 n=120 以后最大乘积的值都是固定的)

因此应该用贪心的思想。

代码

class Solution {public:int cuttingRope(int n) {if(n<=3){return n - 1;}int flag = 1000000007;long sum = 1;while(n > 4){sum = (sum * 3) % flag;n -= 3;}return (sum * n) % flag;}
};

剪绳子(动规、数论、贪心)相关推荐

  1. 导弹拦截(动规,贪心)

    题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...

  2. 剪绳子(动态规划、贪心算法)

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

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

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

  4. CF2B The least round way(贪心+动规)

    题目 CF2B The least round way 做法 后面\(0\)的个数,\(2\)和\(5\)是\(10\)分解质因数 则把方格中的每个数分解成\(2\)和\(5\),对\(2\)和\(5 ...

  5. leetcode 121. 买卖股票的最佳时机 (贪心 + 动规 + 双指针

    贪心的思路: 得到最小值,再挨个用数组中的值减去最小值,最终值取一个最大的 class Solution { public:int maxProfit(vector<int>& p ...

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

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

  7. 动态规划-剪绳子问题

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

  8. bzoj3875: [Ahoi2014Jsoi2014]骑士游戏 spfa处理有后效性动规

    bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏 Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的 ...

  9. 剑指Offer算法笔记(Java)剪绳子

    11.剪绳子 描述 给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m . n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1 ...

最新文章

  1. l#039;oracle 酒,【金钟庄园副牌干红葡萄酒Carillon de L#039;angelus】价格_年份_评分 - 酒窝网官网...
  2. 2020互联网校招薪资列表及谈薪注意事项
  3. Hibernate占位符问题[use named parameters or JPA-style positional parameters instead.]
  4. 个人计算机技术分享,一个计算机类本科毕业设计分享
  5. Mongodb亿级数据量的性能测试zz
  6. SOLID,GRASP和面向对象设计的其他基本原理
  7. java fields是_一个快速生成R2.java中fields的插件
  8. OpenGL ES 2 o 初探
  9. 【BZOJ3489】A simple rmq problem(树套树)
  10. 通过Expression Tree来扩展MVC中的HtmlHelper 和 UrlHelper
  11. Linux 加密压缩与解压
  12. NOI题库1.11编程基础之二分查找 矩形分割
  13. 落的多音字组词有哪些
  14. Java的指针碰撞简介
  15. (纪中)2162. 方格纸(square)【差分+前缀和】
  16. 解决docker中启动Spring Boot微服务注册在Eureka后无法访问的问题
  17. python中复数类型的实部和虚部都是浮点数_Python合集之Python数据类型(一)
  18. html 图片放大保证不失真,教你如何在保证图片不失真的情况下缩小图片大小
  19. cmd 下登陆ftp及相关操作
  20. 挂载硬盘 linux_Linux怎么挂载移动硬盘光盘U盘之案例分享

热门文章

  1. 基于 TI Sitara系列 AM64x核心板——程序自启动说明
  2. Flunent-流体仿真理论和软件操作
  3. [aapt包管理]aapt查询Apk最低支持的Android版本
  4. 浅谈 NATIVE SQL
  5. 创意苹果LOGO灯iPhone6 Plus发光灯苹果6荧光灯苹果4.7/5.5LED灯
  6. 计算机操作系统设备管理ppt,计算机操作系统设备管理.ppt
  7. 3D游戏建模到底难不难学?
  8. Bootstrap5 网格系统讲解
  9. react中 Ender键 触发事件数(输入框)
  10. pycharm 常用插件,常用插件推荐