题目描述
给定一个正整数k,找出n个数x1,x2…xn(n>=2)。使得x1+x2+…xn=k,并且使得x1*x2…*xn的值最大。返回这个最大值max。
解题思路:本题最开始是想要利用数学的柯西不等式进行求解,但发现不行,因为等号成立时x1,x2…xn都要要求相等,但k不一定能被整除。
然后我又想到了“分治”的思想,即将k分成2个数相加,再把这两个数也分成两个数相加,分别计算这两个数乘积的最大值,部分是最大值,整体也会是最大值,但最后结果是超时了。
最后,其实问题很简单,要想乘积最大,则n个数肯定是2或3的集合
为什么呢?
x1、x2、x3、…、xn中,不可能有大于或等于5的数,这是因为,5<2×3,6<3×3,…,也不可能有三个或三个以上的2,因为三个2的积小于两个3的积
则我们只需要把k分解为a个3与b个2的集合即可
这里也有个问题,就是当k%3=1的时候,2的个数为0,这样显然不行,因为最后乘的是个1,肯定会让结果偏小
怎么解决呢?
分出个3即可,此时3的个数减少了1,2的个数变为2,此时3^(a-1)*4 > 3^a,比上面情况要大
代码如下:
#include<stdio.h>
unsigned long long maxMultiNum=1;
unsigned long long pow1(int num,int beMultiNum)
{
unsigned long long res = 1;
for(int i=0;i<num;i++)
{
res*=(beMultiNum);
}
return res;
}
int main()
{
int num,i,res;
scanf("%d",&num);
int threeCount = num / 3;
int twoCount = (num%3)/2;
if(twoCount==0)//说明模3余1,则借3,则有两个2了
{
threeCount--;
twoCount+=2;
}
//printf("%d有%d个3与%d个2组成\n",num,threeCount,twoCount);
maxMultiNum = (pow1(threeCount,3)*pow1(twoCount,2));
printf("%lld\n",maxMultiNum);
return 0;
}
这样就很简单了,之前都没发现这个规律。