剑指 Offer 14- I. 剪绳子 + 动态规划 + 数论
剑指 Offer 14- I. 剪绳子
题目链接
还是343. 整数拆分的官方题解写的更清楚
本题说的将绳子剪成m段,m是大于1的任意一个正整数,也就是必须剪这个绳子,至于剪成几段,每一段多长,才能使得乘积最大,这就是要求解的问题了
【解题思路1】动态规划
对于的正整数 n,当 n≥2 时,可以拆分成至少两个正整数的和。令 k 是拆分出的第一个正整数,则剩下的部分是 n−k,n−k 可以不继续拆分,或者继续拆分成至少两个正整数的和。由于每个正整数对应的最大乘积取决于比它小的正整数对应的最大乘积,因此可以使用动态规划求解。
- dp数组的含义: dp[i] 表示将正整数 i 拆分成至少两个正整数的和之后,这些正整数的最大乘积。
- 边界条件: 0 不是正整数,1 是最小的正整数,0 和 1 都不能拆分,因此 dp[0]=dp[1]=0。
状态转移方程:
当 i≥2 时,假设对正整数 i 拆分出的第一个正整数是 j(1≤j<i),则有以下两种方案:
- 将 i 拆分成 j 和 i−j 的和,且 i−j 不再拆分成多个正整数,此时的乘积是 \(j×(i−j)\);
- 将 i 拆分成 j 和 i−j 的和,且 i−j 继续拆分成多个正整数,此时的乘积是 \(j×dp[i−j]\)。
因此,当 j 固定时,有 \(dp[i]=max(j×(i−j),j×dp[i−j])\)。由于 j 的取值范围是 1 到 i−1,需要遍历所有的 j 得到 dp[i] 的最大值,因此可以得到状态转移方程如下:
\(dp[i]= \max_{1≤j<i} {(j×(i−j),j×dp[i−j])}\)
最终得到 dp[n] 的值即为将正整数 n 拆分成至少两个正整数的和之后,这些正整数的最大乘积。
class Solution {
public int cuttingRope(int n) {
int[] dp = new int[n + 1];
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
dp[i]= Math.max(dp[i], Math.max(j * (i - j), j * dp[i - j]));
}
}
return dp[n];
}
}
【解题思路2】数学:函数极值
直觉上把数拆的越平均他们的积越大。拆分的整数越接近自然参数e,他们的乘积的越大。
数学证明:定义函数 f(x) 表示将给定的正整数 n 拆分成尽可能多的正数 x 的情况下的最大乘积,则可以将 n 分成 \(\frac{n}{x}\) 项,此时 \(f(x)=x^{\frac{n}{x}}\), 通过求导可得f(x)在x=e时取最大值,f(3)>f(2),x=3 时,可以得到最大乘积。
根据 n 除以 3 的余数进行分类讨论:
- 如果余数为 0,则将 n 拆分成 m 个 3;
- 如果余数为 1,因此将 n 拆分成 m-1 个 3 和 2 个 2;
- 如果余数为 2,则将 n 拆分成 m 个 3 和 1 个 2。
上述拆分的适用条件是 n≥4。如果 n≤3,则上述拆分不适用,需要单独处理
- 如果 n=2,则唯一的拆分方案是 2=1+1,最大乘积是 1×1=1;
- 如果 n=3,则拆分方案有 3=1+2=1+1+1,最大乘积对应方案 3=1+2,最大乘积是1×2=2
这两种情形可以合并为:当 n≤3 时,最大乘积是 n-1。
class Solution {
public int cuttingRope(int n) {
if (n <= 3) {
return n - 1;
}
int quotient = n / 3;
int remainder = n % 3;
if (remainder == 0) {
return (int) Math.pow(3, quotient);
} else if (remainder == 1) {
return (int) Math.pow(3, quotient - 1) * 4;
} else {
return (int) Math.pow(3, quotient) * 2;
}
}
}
剑指 Offer 14- I. 剪绳子 + 动态规划 + 数论的更多相关文章
- 【Python】剑指offer 14:剪绳子
题目:给你一根长度为n的绳子,请把绳子剪成m段 (m和n都是整数,n>1并且m>1)每段绳子的长度记为k[0],k[1],-,k[m].请问k[0]k[1]-*k[m]可能的最大乘积是多少 ...
- 剑指offer 面试题. 剪绳子
题目描述 给你一根长度为n的绳子,请把绳子剪成整数长的m段(m.n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m].请问k[0]xk[1]x...xk[ ...
- 【Java】 剑指offer(14) 二进制中1的个数
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把 ...
- 剑指Offer 14. 链表中倒数第k个结点 (链表)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 题目地址 https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?t ...
- [剑指offer] 14. 链表中倒数第K个节点+翻转+逆序打印+合并两个排序链表 + 链表相交(第一个公共节点) (链表)
题目描述 输入一个链表,输出该链表中倒数第k个结点. 思路: 两个指针,起始位置都是从链表头开始,第一个比第二个先走K个节点,当第一个走到链表尾时,第二个指针的位置就是倒数第k个节点.(两指针始终相 ...
- 剑指offer 14. 链表中倒数第 k 个结点
14. 链表中倒数第 k 个结点 题目描述 输入一个链表,输出该链表中倒数第k个结点 法一:快慢指针 快指针先走 k 步,等快指针到达尾部时,慢指针所指结点即是倒数第 k 个结点 public cla ...
- 剑指offer 14:链表中倒数第k个节点
题目描述 输入一个链表,输出该链表中倒数第k个结点. /* public class ListNode { int val; ListNode next = null; ListNode(int va ...
- 剑指offer(14)
题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 思路: 这里有个细节,我们发现,6节点的子节点在操作之后并没有发生变化,所以等会我们在交换的时候,交换的不是节点的数值,而是整个节点. 另外我们进 ...
- 剑指offer 14 调整数组顺序使奇数位于偶数前面
牛客网上的题目还有一个额外的要求,就是不改变数组原始的前后数据,这种可以用队列来存储,或者把前后比较变为相邻的元素比较. 这个题目,主要要考察扩展性,用func函数就实现了扩展性.只需要改func函数 ...
随机推荐
- Codeforces 102394I Interesting Permutation 思维
题意: 你有一个长度为n的序列a(这个序列只能使用[1,n]区间内的数字,每个数字只能使用一次),通过a序列可以构造出来三个相同长度的序列f.g.h For each 1≤i≤n, fi=max{a1 ...
- 二分图最大权匹配问题&&KM算法讲解 && HDU 2255 奔小康赚大钱
作者:logosG 链接:https://www.cnblogs.com/logosG/p/logos.html (讲解的KM算法,特别厉害!!!) KM算法: 现在我们来考虑另外一个问题:如果每个员 ...
- 同时拿到BATJMD的Offer是怎样的一种体验?
写在前面 又到了收割Offer的季节,你准备好了吗?曾经的我,横扫各个大厂的Offer.还是那句话:进大厂临时抱佛脚是肯定不行的,一定要注重平时的总结和积累,多思考,多积累,多总结,多复盘,将工作经历 ...
- Butterfly美化
Butterfly美化 首先提示,本文量特别大哦!基本上有所有的美化,还在持续更新ing,谨慎入坑......... 主题配置文件修改 基础配置 最最最开始的,好不容易搭建了自己的个人博客,当然要写上 ...
- Leetcode(20)-有效的括号
给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. 注意空字符串可被认 ...
- 北京网络赛G BOXES 大模拟+BFS
题目描述 Description There is a strange storehouse in PKU. In this storehouse there are n slots for boxe ...
- USB2.0协议学习笔记---基本概念
概念 USB是一种串行通信总线(Universal Serial Bus),经历的版本有USB1.0,USB1.1.USB2.0等.USB是一种主从模式的结构,因此它无法在设备与设备.主机与主机之间 ...
- value-key
value-key object 如果 Select 的绑定值为对象类型,请务必指定 value-key 作为它的唯一性标识. value-key 作为 value 唯一标识的键名,绑定值为对象类型时 ...
- vue & this.$route & this.$router
vue & this.\(route & this.\)router const User = { template: '<div>User</div>' } ...
- css scroll text without wrap & webkit-scrollbar
css scroll text without wrap hidden webkit-scrollbar .tabs-title-box::-webkit-scrollbar, .tabs-conte ...