解法一
一、相关知识:
在高中的时候都学到过,N个数和一定时,其积有最大值,当且仅当这N个数相等时取得最大。
只有两个数时公式为:
a 2 + b 2 ≥ 2 a b ( 当 且 仅 当 a = b 时 等 号 成 立 ) a^2 + b^2 \ge2ab \left(当且仅当a=b时等号成立\right) a2+b2≥2ab(当且仅当a=b时等号成立)
多个数时的公式:
1
+
a
2
+
a
3
+
a
4
+
a
5
+
a
6
+
⋅
⋅
⋅
+
a
n
n
≥
a
1
a
2
a
3
a
4
a
5
⋅
⋅
⋅
a
n
n
(
当
且
仅
当
a
1
=
a
2
=
a
3
=
⋅
⋅
⋅
=
a
n
时
等
号
成
立
)
\frac{_1+a_2+a_3+a_4+a_5+a_6+···+a_n}{n}\ge\sqrt[n]{a_1a_2a_3a_4a_5···a_n} \\\left(当且仅当a_1=a_2=a_3=···=a_n时等号成立\right)
n1+a2+a3+a4+a5+a6+⋅⋅⋅+an≥na1a2a3a4a5⋅⋅⋅an(当且仅当a1=a2=a3=⋅⋅⋅=an时等号成立)
二、分析:(文中NumGiven为所给的整数)
根据这两个公式我们可以有一个大致的方向:尽量将正整数分为 m − 1 m-1 m−1个大小大相同且为 n n n的正整数,和另外一个正整数,其中$ m=2、3、4···$
我们首先以整数 10 为例,10 可以被分为
拆分成的数集 | 乘积 |
---|---|
2 2 2 2 2 2\ 2\ 2\ 2\ 2 2 2 2 2 2 | 2 × 2 × 2 × 2 × 2 2\times2\times2\times2\times2 2×2×2×2×2 |
3 3 3 1 3\ 3\ 3 \ 1 3 3 3 1 | 3 × 3 × ( 3 + 1 ) 3\times3\times\left(3+1\right) 3×3×(3+1) |
4 4 2 4 \ 4\ 2 4 4 2 | 4 × 4 × 2 4\times4\times2 4×4×2 |
5 5 5\ 5 5 5 | 5 × 5 5\times5 5×5 |
从上述表中我们可以看出,拆分出的相等的元素的个数为NumGiven/n
,另外一个正整数为NumGiven%n
表中第二行为 3 × 3 × ( 3 + 1 ) 3\times3\times\left(3+1\right) 3×3×(3+1)是因为当余数为 1 时,拆分所得的 m − 1 m-1 m−1个值为 n n n的正整数相乘再乘 1 的值远没有 m − 2 m-2 m−2个值为 n n n的正整数相乘再与 n + 1 n+1 n+1相乘所得的结果大。(一个正整数共拆分为m个正整数)
当余数不为 1 时,拆分所得的 m − 1 m-1 m−1个值为 n n n的正整数相乘再乘余数的值远比 m − 2 m-2 m−2个值为 n n n的正整数相乘再与 n + 余 数 n+余数 n+余数相乘所得的结果大
推导如下:(令余数为r)
n
m
−
1
⋅
r
n
m
−
2
⋅
(
n
+
r
)
=
n
r
n
+
r
=
r
1
+
r
n
因
为
r
n
<
1
且
由
上
述
假
设
r
≥
2
所
以
可
得
n
m
−
1
⋅
r
n
m
−
2
⋅
(
n
+
r
)
>
1
\frac{n^{m-1}\cdot r}{n^{m-2}\cdot{\left(n+r\right)}}=\frac{nr}{n+r}=\frac{r}{1+\frac{r}{n}} \\因为\frac{r}{n}<1且由上述假设r\ge2所以可得 \\\frac{n^{m-1}\cdot r}{n^{m-2}\cdot{\left(n+r\right)}}>1
nm−2⋅(n+r)nm−1⋅r=n+rnr=1+nrr因为nr<1且由上述假设r≥2所以可得nm−2⋅(n+r)nm−1⋅r>1
到这,我们可以大概得出解题的流程:
-
求出
NumGiven/n
以及NumGiven%n
的值。 -
如果
NumGiven%n == 0
则当前最大值为Pow(n,NumGiven/n-1)
,并且跳转至4,反之则跳转至3。 -
如果
NumGiven%n == 1
则当前最大值为Pow(n,NumGiven/n-1)*(n+1)
,反之当前最大值为Pow(n,NumGiven/n)*(NumGiven%n)
。 -
比较当前最大值与前一个最大值的大小,更新数据,变动n的值。
-
判断n是否大于
NumGiven
,若果是则跳转到5,反之跳转到1。 -
退出循环,输出最大值。
算法时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)
按照上述算法编写代码会出现当输入的整数位2,3时输出错误的现象,至于为什么会出现错误读者可带入算法进性检验。下面提供两种解决方案:
- 在算法最开始的时候判断输入的整数是否大于3,如果是则调用算法,反之则直接输出
NumGiven-1
- 在程序中增加判断语言,对可能出现的错误现象进行修正,笔者采用的就是第二种方法。
代码如下:
int integerBreak(int n){
int max=-1; //设定初始的最大值位-1,便于对最大值进行覆盖填写
int temp_max=1; //存放当前最大值的变量
for(int i=2;i<n;i++) //从2开始遍历直到n-1
{
int num=n/i; //计算出该整数包含多少个n
temp_max=pow(i,num);//按照分析的算法步骤先处理m-1个值为n的正整数,再对余数进行处理。
if(n%i!=0) //余数为0时,应直接返回数值,不能再乘余数
{
if(n%i==1&&num!=1) //该步骤用于处理的正整数为3的特殊情况。
temp_max=(temp_max/i)*(i+n%i);
else`在这里插入代码片`
temp_max*=n%i;
}
max = max>temp_max?max:temp_max;
temp_max=1;
}
if (max==-1) //该步骤用于处理输入的正整数位2的特殊情况
return 1;
return max;
}
解法二
一、分析:
通过解法一我们可以求出乘积的最大值,也可以求出当n值位多少时输出最大,再计算完58个实例之后发现,乘积的最大值总是在 n = 3 n=3 n=3处取得。下面对为什么总是再 n = 3 n=3 n=3处取得进行粗略的分析。
由解法一的分析我们可知,只有当被分成所有整数都相等时才能取得乘积最大,又因为要分成正整数。实现不了完全相等,这里我们先假设只需求得被分成所有数的乘积最大。于是可以列出下面的式子:
M
a
x
=
m
a
x
{
x
n
x
}
Max \ \ \ =\ \ \ max\{x^\frac{n}{x}\}
Max = max{xxn}
式子中的x为均等分之后的值。使用Maltlab画出图像有:
该图像时从1到58对其进行均等分割并且相乘得到的图像,由图像可以粗略的看出当满足正整数条件的时候,x=3时乘积值最大,故由此可优化解法一,我们无需遍历,可直接默认分割得到的整数大部分都为3,即n=3。因此我们可以优化时间复杂度至 O ( 1 ) O(1) O(1)。代码与方法一大致相同,留做读者思考。
既然看到这里了,可以支持一下我的博客吗 ⇒ ⇒ ⇒ \Rightarrow\Rightarrow\Rightarrow ⇒⇒⇒白羊的博客传送门