例如,4可以分为1+1+1+1;2+1+1;2+2;等等,其中乘积最大的是2*2=4;
该题初始要做一些思考,得到的一个几个重要结论是
其乘积最大的分法中首先不能有1,即至少为2;
其乘积最大的分法中不能大于4,即不会有5;若有5,则可分为2*3,其乘积肯定比原来的数要大。
而4可以分为2*2,所以可以断定其乘积最大的分法中,所有元素皆为2和3;
也就是任何一个大于4的整数可以写成n=2*x+3*y; 其乘积是z=(2^x)*(3^y),我们要做的事找到其中最大的z。
方法一:既然所有元素皆为2或者3,我们假设其最大乘积为f(n),且f(n)=Math.max(f(n-2)*2,f(n-3)*3);所以可以用递归的方法:
package Shenzhen; public class Yang{ static int f(int x) { if(x==2) { return 2; }if(x==3) { return 3; }if(x==4){ return 4; }else { return Math.max(f(x-2)*2, f(x-3)*3); } } public static void main(String[] args) { System.out.println(f(9)); } }当然,大家都知道,递归的方法,数字大了就悲剧了。计算时间指数级上升。
方法二:任何一个大于4的整数可以写成n=2*x+3*y; 其乘积是z=(2^x)*(3^y),我们要做的事找到其中最大的z。
package Shenzhen; public class Yang{ static void f(int n) { for(int x=0;x<=n/2;x++) { if((n-2*x)%3==0) { int y=(n-2*x)/3; System.out.print (2+"*"+x+"+"+3+"*"+y+"="+n+" "); System.out.println(2+"^"+x+"+"+3+"^"+y+"="+Math.pow(2, x)*Math.pow(3, y)); } } } public static void main(String[] args) { f(9); } }稍微测试便可发现规律:
f(12):
输出结果:
2*0+3*4=12 2^0+3^4=81.0 2*3+3*2=12 2^3+3^2=72.0 2*6+3*0=12 2^6+3^0=64.0
f(14)的输出:
2*1+3*4=14 2^1+3^4=162.0 2*4+3*2=14 2^4+3^2=144.0 2*7+3*0=14 2^7+3^0=128.0 明显能看出,其乘积最大的情况就是3最多的情况,而2最少。
其实任何一个大于4的整数都是3的倍数,或者3的倍数加一,或者3的倍数加二
所以对任何一个较大的n,我们求得是那个y,y=n/3,或者(n-4)/3 ,或者(n-2)/3 ;
定义一个方法y(n)求 y:
static int y(int n) { if(n%3==0) { return n/3; }else if(n%3==1){ return (n-4)/3; }else { return (n-2)/3; } }所以任意n,如题乘积最大的分法是:
n=2*(n-3*y)/2+ 3* y ;
其乘积为:2^( (n-3*y)/2 ) * 3^y