剪绳子(动规、数论、贪心)

文章目录

  • 题目
    • 数论
      • 思路
      • 代码
      • 复杂度分析
    • 动规一
      • 思路
      • 代码
    • 动规二
      • 思路
      • 代码
  • 对最终结果取模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+10);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;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/443800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速幂实现pow函数(从二分和二进制两种角度理解快速幂)

文章目录迭代实现快速幂思路int的取值范围快速幂从二进制的角度来理解从二分法的角度来理解代码复杂度分析进阶——超级次方思路倒序快速幂正序快速幂代码复杂度分析迭代实现快速幂 实现 pow(x, n) &#xff0c;即计算 x 的 n 次幂函数&#xff08;即&#xff0c;xn&#xff0…

备份MySQL数据库的命令

备份MySQL数据库的命令 mysqldump -hhostname -uusername -ppassword databasename > backupfile.sql 备份MySQL数据库为带删除表的格式 备份MySQL数据库为带删除表的格式&#xff0c;能够让该备份覆盖已有数据库而不需要手动删除原有数据库。 mysqldump -–add-drop-…

n位数的全排列(需要考虑大数的情况)

文章目录题目思路代码题目 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1 输出: [1,2,3,4,5,6,7,8,9] 说明&#xff1a; 用返回一个整数列表来代替打印 n 为正整数 …

正则表达式匹配(动规)

文章目录题目思路转移方程特征再探 i 和 j代码题目 请实现一个函数用来匹配包含 . 和 * 的正则表达式。模式中的字符 . 表示任意一个字符&#xff0c;而 * 表示它前面的字符可以出现任意次&#xff08;含0次&#xff09;。在本题中&#xff0c;匹配是指字符串的所有字符匹配整…

在循环递增一次的数组中插入元素

文章目录题目思路如何建立左右区间&#xff1f;如何查找最高点&#xff1f;那我们怎么判断 num 到底处于什么样的位置呢&#xff1f;如何确定插入位置&#xff1f;插入元素代码题目 给一个只循环递增一次的数组 res&#xff0c;res 满足首元素大于等于尾元素&#xff0c;形如&…

Unable to find 'struts.multipart.saveDir' property setting.

Unable to find struts.multipart.saveDir property setting. 今天在做工作的时候遇到了这个问题&#xff0c;后来经过百度&#xff0c;终于知道了原因&#xff0c;现在记录下来&#xff0c;以备以后查看。 1.struts.multipart.saveDir没有配置 2.struts.multipart.saveDir用…

表示数值的字符串(有限状态自动机与搜索)

文章目录题目思路一代码一思路二代码二题目 思路一 考察有限状态自动机&#xff08;参考jyd&#xff09;&#xff1a; 字符类型&#xff1a; 空格 「 」、数字「 0—9 」 、正负号 「 」 、小数点 「 . 」 、幂符号 「 eE 」 。 状态定义&#xff1a; 按照字符串从左到右的…

树的子结构

文章目录题目深搜深搜代码广搜广搜代码题目 输入两棵二叉树A和B&#xff0c;判断B是不是A的子结构。(约定空树不是任意一个树的子结构) B是A的子结构&#xff0c; 即 A中有出现和B相同的结构和节点值。 例如: 给定的树 A: 给定的树 B&#xff1a; 返回 true&#xff0c;因为…

写题过程中碰见的小问题

文章目录和--vector二维vector的初始化数组中最大的数max_element()数组所有元素之和accumulate()vector数组去重对pair类型的vector排序对元素都为正整数的vector利用sort默认的升序排列进行降序排列一维数组转二维数组size_t和int如何不用临时变量交换两个数?将类函数的形参…

LeetCode——二叉树序列化与反序列化

文章目录题目思路问题一问题二代码实现题目 请实现两个函数&#xff0c;分别用来序列化和反序列化二叉树。 设计一个算法来实现二叉树的序列化与反序列化。不限定序列 / 反序列化算法执行逻辑&#xff0c;你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序…

jsp中生成的验证码和存在session里面的验证码不一致的处理

今天在调试项目的时候发现&#xff0c;在提交表单的时候的验证码有问题&#xff0c;问题是这样的&#xff1a;就是通过debug模式查看得知&#xff1a;jsp页面生成的验证码和表单输入的页面输入的一样&#xff0c;但是到后台执行的时候&#xff0c;你会发现他们是不一样的&#…

求1~n这n个整数十进制表示中1出现的次数

文章目录题目思路代码复杂度分析题目 输入一个整数 n &#xff0c;求1&#xff5e;n这n个整数的十进制表示中1出现的次数。 例如&#xff0c;输入12&#xff0c;那么1&#xff5e;12这些整数中包含1 的数字有1、10、11和12。可得1一共出现了5次。 思路 将个位、十位……每位…

求数字序列中的第n位对应的数字

文章目录题目思路代码复杂度分析致谢题目 数字以0123456789101112131415…的格式序列化到一个字符序列中。在这个序列中&#xff0c;第5位&#xff08;从下标0开始计数&#xff09;是5&#xff0c;第13位是1&#xff0c;第19位是4&#xff0c;等等。 请写一个函数&#xff0c…

一学就废的归并排序

文章目录其他与排序有关的文章原理代码实现复杂度分析其他与排序有关的文章 一学就废的三种简单排序【冒泡、插入、选择】 原理 归并排序&#xff08;Merge sort&#xff09;&#xff1a; 归并排序对元素 递归地 进行 逐层折半分组&#xff0c;然后从最小分组开始&#xff0c…

神奇的x -x,Lowbit函数的实现方式!

文章目录-xx & -x&#xff0c;当x为偶数时x & -x&#xff0c;当x为奇数时x&-x 的实际用途-x -x 在二进制里表示对 x 的二进制按位取反(~x)之后再加 1 &#xff0c;即 -x ~x1x & -x&#xff0c;当x为偶数时 在执行 x & -x 时&#xff0c;若 x 为偶数&am…

JAVA实现把指定文件夹下的所有文件压缩成zip包

1.代码如下&#xff1a; package cn.gov.csrc.base.util;import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import…

树状数组的相关知识 及 求逆序对的运用

文章目录树状数组概念前缀和和区间和树状数组原理区间和——单点更新前缀和——区间查询完整代码离散化sort函数unique函数去重erase函数仅保留不重复元素通过树状数组求逆序对树状数组概念 树状数组又名二叉索引树&#xff0c;其查询与插入的复杂度都为 O(logN)&#xff0c;其…

二叉搜索树相关知识及应用操作

文章目录概念查找二叉搜索树的第k大节点概念 二叉查找树&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又名&#xff1a;二叉搜索树&#xff0c;二叉排序树&#xff09;——它或者是一棵空树&#xff0c;或者是具有下列性质的二叉树&#xff1a; 若它的…

二叉树相关知识及求深度的代码实现

文章目录树二叉树满二叉树和完全二叉树二叉树的性质代码实现求二叉树的深度树 树是一种非线性的数据结构&#xff0c;它是由n个有限结点组成一个具有层次关系的集合。 树的相关名词&#xff1a; 根节点&#xff1a;没有前驱结点的结点。父节点&#xff0c;子节点&#xff1a…

平衡树相关知识及如何判断一棵树是否平衡

文章目录概念代码实现判断一棵二叉树是否为平衡树概念 平衡树(Balance Tree&#xff0c;BT) 指的是&#xff0c;任意节点的子树的高度差都小于等于1。 常见的符合平衡树的有&#xff1a; B树&#xff08;多路平衡搜索树&#xff09;AVL树&#xff08;二叉平衡搜索树&#xf…