343. Integer Break

Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.

For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).

Note: You may assume that n is not less than 2 and not larger than 58.

题目含义:将一个正数拆分出多个数的和。求这些数字能产生的最大乘积

方法一:

1         if (n == 2 || n == 3) return n - 1;
2         int[] dp = new int[n + 1];// dp[i]表示将i各种拆分后,所能得到的最大值
3         dp[1] = 1;//第一个数字1,只能是1
4         for (int i = 2; i <= n; i++)
5             for (int j = 1; j <= i - 1; j++)
6                 //将数字i分为i-j和j,比如i=8,j=3,会被拆分为5和3. 这里会出现两种情况,一种是5*3的乘积,另外一种是dp[5](数字5被拆分后得到的最大乘积)*3.取两种情况中最大的值最为dp[i]
7                 dp[i] = Math.max(dp[i], Math.max(dp[i - j] * j, (i - j) * j));
8         return dp[n];

 

方法二:

首先证明拆出的因子大于 4 是不行的。设 x 是一个因子,x>4,那么可以将这个因子再拆成两个因子 x2和 2,易证 (x2)×2>x。所以不能有大于 4 的因子。

4 这个因子也是可有可无的,4=2+24=2×2。因此 4 这个因子可以用两个 2 代替。

除非没有别的因子可用,1 也不能选作因子。一个数 x 当它大于 3 时,有 (x2)×2>(x1)×1

这样呢,就只剩下 2 和 3 这两个因子可以选了。下面再证明 3 比 2 好。

一个数 x=3m+2n,那么 f=3m×2n=3m×2x3m2 可以对它取个对数。 

lnf===mln3+nln2mln3+x3m2ln2x2ln2+(ln332ln2)m

 

其中 ln332ln2>0 所以 f 是 m 的增函数,也就是说 m 越大越好。所以 3 越多越好。

再多说一句,如果拆出的因子不限于整数的话,可以证明e=2.718 是最佳的选择。感兴趣的可以试着证明一下。

 

另外一种观察法:

我们先拿num=3为例,结果为[0, 1, 1, 2],得到3以内数字的结果之后,4~7的结果可以在此基础上确定,如下0~3二进制表示为:

 bin                ret

000                0

001                1

010                1

011                2

4~7二进制表示为:

  bin                ret

100                1

101                2

110                2

111                3

从上面分析可以看出,4~7除了最高位其他位和0~3是相同的,而最高位是1,这样4~7的结果就可以在0~3的基础上分别加1获得,题目就很容易解决了

 

 1     public int integerBreak(int n) {
 2        int res=1;
 3        if (n==2 || n==3)return n-1;
 4        while (n>4)
 5        {
 6            res*=3;
 7            n-=3;
 8        }
 9        return res*n;        
10     }

 

posted @ 2017-10-19 18:13  daniel456  阅读(114)  评论(0编辑  收藏  举报