题目详情

给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

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

示例 2:

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

说明: 你可以假设 n 不小于 2 且不大于 58。

题目解析

关键是找到状态方程, 我们设置dp[i]表示整数i的最大乘积, 那么把问题分成子问题, 我们发现dp[i] 与前面的dp[1] ~ dp[i-1]都有关系, 关系很容易找到

dp[i] = max(j * (i-j), j * dp[i - j])  j = 1,2 ······ i -1

而初始条件dp[1] = 1, dp[2] = 2, dp[3] = 3

为什么要加上 j * (i-j)的比较呢, 是为了处理dp[i] < i的情况, 例如

n=4, 那么如果不考虑 j * (i-j), 因为dp[2] = 1 <2, 所以最终的结果为3, 但是其实把4分成2 * 2, 最终结果为4. 所以要加上 j * (i-j) 直接把i分成两个数字i, j-i,的情况。

那么可以由此得到第一种dp代码

代码一 动态规划

class Solution {
public:
int integerBreak(int n) {
vector <int> dp(n +1, 0);
int tmp = 0;
dp[0] = 0;
dp[1] = 1;
dp[2] = 1; for (int i = 3; i <= n ; i++) {
tmp = 0;
for (int j = 1; j <= i - 1; j++) {
tmp = max(tmp, max(dp[j] * (i-j), j * (i - j)));
}
dp[i] = tmp;
} return dp[n];
}
};

时间复杂度为0(n^2)

代码2 数学推倒

有一些其他的博客给了更加速度快的算法, 有一种是利用数学推导, 得出要想使乘积最大, 只需要尽可能的多分成3, 其次是二

数学推导过程

由均值不等式(n个数的算术平均数大于等于它们的几何平均数):

得:当把输入的n拆分成几个相等的数时它们的积最大。

那么问题来了,拆分成几个呢?

为了方便使用导数,我们先假设我们可以把n拆分成实数。那么设每一个数为x,则一共有n/x个数。

设它们的积为f(x),则f(x)=x(n/x),那么怎么求f(x)最大值呢?求导数!

f′(x)=(n/x2) * x(n/x) * (1-lnx)

当x=e时取极大值。

而我们题目里规定x为整数,那么我们只需要取的x越靠近e越好。那么2<e<3,而且e=2.71828…,所以取3是最好的,如果取不到3就取2。

幂运算复杂度为O(lgn),所以这个算法复杂度为O(lgn)。

代码如下

class Solution {
public:
int integerBreak(int n) {
if(n == 2)
return 1;
else if(n == 3)
return 2;
else if(n%3 == 0)
return pow(3, n/3);
else if(n%3 == 1)
return 2 * 2 * pow(3, (n - 4) / 3);
else
return 2 * pow(3, n/3);
}
};

LeetCode343 整数拆分详解的更多相关文章

  1. [Swift]LeetCode343. 整数拆分 | Integer Break

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  2. 【转】linux 原子整数操作详解

    原文网址:http://blog.csdn.net/hunanchenxingyu/article/details/8994379 printk(“%d\n”,atomic_read(&v)) ...

  3. Extjs6(特别篇)——项目自带例子main.js拆分详解

    本文基于extjs6.0.0 一.拆分代码来看看 1.主页面main是个tab页: 写一些页面的依赖: 标明页面的controller和viewModel Ext.define('Learning.v ...

  4. MySQL 水平拆分与垂直拆分详解

    前言:说到优化mysql,总会有这么个回答:水平拆分,垂直拆分,那么我们就来说说什么是水平拆分,垂直拆分. 一.垂直拆分 说明:一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将 ...

  5. Newtonsoft.Json C# Json序列化和反序列化工具的使用、类型方法大全 C# 算法题系列(二) 各位相加、整数反转、回文数、罗马数字转整数 C# 算法题系列(一) 两数之和、无重复字符的最长子串 DateTime Tips c#发送邮件,可发送多个附件 MVC图片上传详解

    Newtonsoft.Json C# Json序列化和反序列化工具的使用.类型方法大全   Newtonsoft.Json Newtonsoft.Json 是.Net平台操作Json的工具,他的介绍就 ...

  6. 详解CorelDRAW中如何合并与拆分对象

    合并两个或多个对象可以创建带有共同填充和轮廓属性的单个对象,以便将这些对象转换为单个曲线对象.可以合并的对象包括矩形.椭圆形.多边形.星形.螺纹.图形或文本等,本教程将详解CorelDRAW中关于合并 ...

  7. 【转载】C语言itoa()函数和atoi()函数详解(整数转字符C实现)

    本文转自: C语言itoa()函数和atoi()函数详解(整数转字符C实现) 介绍 C语言提供了几个标准库函数,可以将任意类型(整型.长整型.浮点型等)的数字转换为字符串. int/float to ...

  8. Hadoop MapReduce执行过程详解(带hadoop例子)

    https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 Map ...

  9. CSS详解

    Web前端开发css基础样式总结 颜色和单位的使用 颜色 用颜色的名字表示颜色,比如:red 用16进制表示演示 比如:#FF0000 用rgb数值表示颜色,rgb(红,绿,蓝),每个值都在0-255 ...

随机推荐

  1. 用Python把20年的GDP、人口以及房价数据进行了可视化

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:CDA数据分析师 提到一线城市,大家马上会想到北上广深这四个超级大都 ...

  2. 因为喜欢所以升级,MyStaging-3.0 继续

    我为什么维护MyStaging 目前该项目只有我一个人在维护,权当学习交流.为什么要继续维护呢,说一千道一万,还是因为喜欢,由于他的简单易用,从而促使我决定对 MyStaging 进行升级,目前 3. ...

  3. 基于Vue的UI框架element el-table表格的自定义排序

    html部分: <el-table-column prop="phoneCache" label="手机缓存包编号" align="center ...

  4. vue组件库用markdown生成文档

    前言: 开发vue组件库需要提供组件的使用文档,最好是有渲染到浏览器的demo实例,既能操作又能查看源代码.markdown作为常用的文档编写载体,如果能在里面直接写vue组件,同时编写使用说明就再好 ...

  5. DJANGO-天天生鲜项目从0到1-008-列表页

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  6. 细说JavaScript 导出 上万条Excel数据

    首先这是个鸡肋的方法 合理的做法是 后端直接生成 前端给个链接就行了 (先说原因与过程最后上代码) 1. 先说说为什么会出现这个需求吧. : 在写运维网站时 自己粗略的看了一下bootstarp-ta ...

  7. BUUCTF-Web Easy Calc

    要素察觉 打开calc.php发现源码 过滤了很多字符.题目一开始提示了有waf,最后通过eval实现计算功能.考虑利用该函数读取flag文件,先尝试弹个phpinfo 被waf拦截,在num参数前面 ...

  8. CentOS6.5安装Oracle11g

    安装前必读: 1.      安装Oracle的虚拟机需要固定IP. 2.      注意安装过程中root用户与oracle用户的切换(su root/su oracle) 3.      环境变量 ...

  9. HTML5+CSS3前端入门教程---从0开始通过一个商城实例手把手教你学习PC端和移动端页面开发第5章CSS盒子模型

    本教程案例在线演示 有路网PC端 有路网移动端 教程配套源码资源 教程配套源码资源 div div 可定义文档中的分区(division). div 标签可以把网页分割为独立的.不同的部分. 可以看成 ...

  10. Python日期和时间_什么是Tick_什么是时间元组_获取当前时间

    Python 日期和时间_什么是 Tick _什么是时间元组: 时间和日期:某年某月某日某时某分某秒 Tick: 时间间隔以 秒 为单位的浮点小数,起始时间为:1970年1月1日0点0分开始 # Ti ...