剪绳子(动规、数论、贪心)
文章目录
- 题目
- 数论
- 思路
- 代码
- 复杂度分析
- 动规一
- 思路
- 代码
- 动规二
- 思路
- 代码
- 对最终结果取模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乘n等于n,对于最大乘积没有提升)。
- 任何大于1的数都可由2和3相加组成(根据奇偶证明)。
- 因为
2*2=1*4
,2*3>1*5
, 所以将数字拆成2和3,能得到的积最大。(4和5还是拆分成2、3更有利) - 因为
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)
动规一
这个版本比较好理解。
思路
- 每段都应该为3或者2(证明段应该为2或3不再赘述)。
- 将
n=2
和n=3
时最大乘积作为不具有规律的特殊值直接返回(因为n<=3时无法切分成3,不具有第一点所说的规律)。 - 动态规划数组dp中
下标为n
的位置保存着长度为n的绳子的最大乘积
(n=2,3时不再此列,已做特殊处理)。 - dp数组的长度:由于定义
dp[i]
为绳长度为i
时的结果,因此dp[n]
为最后一项,所以数组的总长度为n + 1
。 - 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];}
};
动规二
有一点抽象,但是不做特殊值的处理,属于力求包含所有规律的“正规”动规。
思路
- 将
n=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;}
};
剪绳子(动规、数论、贪心)相关推荐
- 导弹拦截(动规,贪心)
题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...
- 剪绳子(动态规划、贪心算法)
一.前言 <剑指Offer>中题14 二.题目 给你一根长度为n的绳子,请把绳子剪成m段(m.n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[ ...
- 剑指Offer 14- I. 剪绳子(Medium)/ 剪绳子 II(Medium)/ 343. 整数拆分(Medium)
剑指Offer 14- II. 剪绳子 II(Medium) 343. 整数拆分(Medium) [题目连接] 题解 剪绳子(数学推导 / 贪心思想,清晰图解) 图解[暴力递归][记忆化技术][动态规 ...
- CF2B The least round way(贪心+动规)
题目 CF2B The least round way 做法 后面\(0\)的个数,\(2\)和\(5\)是\(10\)分解质因数 则把方格中的每个数分解成\(2\)和\(5\),对\(2\)和\(5 ...
- leetcode 121. 买卖股票的最佳时机 (贪心 + 动规 + 双指针
贪心的思路: 得到最小值,再挨个用数组中的值减去最小值,最终值取一个最大的 class Solution { public:int maxProfit(vector<int>& p ...
- 动态规划--09-[剑]剪绳子1[中等]
力扣 力扣 给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m.n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] .请问 k[0]*k[ ...
- 动态规划-剪绳子问题
题目 给你一根长度为n的绳子,请把绳子剪成整数长的m段(m.n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],-,k[m-1].请问k[0]×k[1]×-×k[m]可能 ...
- bzoj3875: [Ahoi2014Jsoi2014]骑士游戏 spfa处理有后效性动规
bzoj3875: [Ahoi2014&Jsoi2014]骑士游戏 Description [故事背景] 长期的宅男生活中,JYY又挖掘出了一款RPG游戏.在这个游戏中JYY会 扮演一个英勇的 ...
- 剑指Offer算法笔记(Java)剪绳子
11.剪绳子 描述 给你一根长度为 n 的绳子,请把绳子剪成整数长的 m 段( m . n 都是整数, n > 1 并且 m > 1 , m <= n ),每段绳子的长度记为 k[1 ...
最新文章
- l#039;oracle 酒,【金钟庄园副牌干红葡萄酒Carillon de L#039;angelus】价格_年份_评分 - 酒窝网官网...
- 2020互联网校招薪资列表及谈薪注意事项
- Hibernate占位符问题[use named parameters or JPA-style positional parameters instead.]
- 个人计算机技术分享,一个计算机类本科毕业设计分享
- Mongodb亿级数据量的性能测试zz
- SOLID,GRASP和面向对象设计的其他基本原理
- java fields是_一个快速生成R2.java中fields的插件
- OpenGL ES 2 o 初探
- 【BZOJ3489】A simple rmq problem(树套树)
- 通过Expression Tree来扩展MVC中的HtmlHelper 和 UrlHelper
- Linux 加密压缩与解压
- NOI题库1.11编程基础之二分查找 矩形分割
- 落的多音字组词有哪些
- Java的指针碰撞简介
- (纪中)2162. 方格纸(square)【差分+前缀和】
- 解决docker中启动Spring Boot微服务注册在Eureka后无法访问的问题
- python中复数类型的实部和虚部都是浮点数_Python合集之Python数据类型(一)
- html 图片放大保证不失真,教你如何在保证图片不失真的情况下缩小图片大小
- cmd 下登陆ftp及相关操作
- 挂载硬盘 linux_Linux怎么挂载移动硬盘光盘U盘之案例分享
热门文章
- 基于 TI Sitara系列 AM64x核心板——程序自启动说明
- Flunent-流体仿真理论和软件操作
- [aapt包管理]aapt查询Apk最低支持的Android版本
- 浅谈 NATIVE SQL
- 创意苹果LOGO灯iPhone6 Plus发光灯苹果6荧光灯苹果4.7/5.5LED灯
- 计算机操作系统设备管理ppt,计算机操作系统设备管理.ppt
- 3D游戏建模到底难不难学?
- Bootstrap5 网格系统讲解
- react中 Ender键 触发事件数(输入框)
- pycharm 常用插件,常用插件推荐