343. Integer Break

问题:

将给定正整数n,拆成多个数。(使得这些数之和=n)

这些数之积最大是多少。

Example 1:
Input: n = 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1.

Example 2:
Input: n = 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36.
 
Constraints:
2 <= n <= 58

  

解法:DP,math

解法一:DP

  • 状态:dp[n]:n被拆分后所得最大乘积
    • 要被拆分的数 n
  • 选择:
    • 拆出去x=1~n-1中任意数,和剩下的数n-x,被拆分后的最大乘积,相乘所得结果中的最大值。
    • MAX {(x:1~n-1)
      • dp[n-x] * x
    • }
  • base:
    • dp[1]=1
    • dp[2]=1

 

⚠️ 注意:当得到 当前数 n 的拆分最大结果 dp[n] 后,

为求解后面的数 >n ,n 自己也可作为乘数,不拆分,因此dp[n] = max(n,dp[n]),用 自己 和 刚才求得结果dp[n] 之间,再求最大值。

 

代码参考:

 1 class Solution {
 2 public:
 3     //dp[n]:maximum product of divide n.
 4     //opt: MAX:(x=1~n-1)
 5     // = dp[n-x] * x
 6     //base:
 7     //dp[1]=1
 8     //dp[2]=1
 9     int integerBreak(int n) {
10         vector<int> dp(n+1,0);
11         int res = 0;
12         dp[1]=1;
13         dp[2]=1;
14         for(int i=3; i<=n; i++) {
15             dp[i-1] = max(i-1, dp[i-1]);
16             //i-1: as itself(not to divide) -> for other element calculate.
17             for(int x=2; x<=i-1; x++) {
18                 dp[i] = max(dp[i], dp[i-x]*x);
19             }
20         }
21         return dp[n];
22     }
23 };

 

解法二:math

思路:要使 拆分n 的乘积取得最大。

我们先考虑,将 n 拆分为两个数 f=x(N-x) (以后在递归拆分这两个数即可)

怎么样才能使得 f 最大,可得:

x=N/2,我们能得到最大。

由于根据题意,我们需要拆分成两个正整数。那么分奇偶性讨论:

  • N为偶数:(N/2)*(N/2)
  • N为奇数:((N+1)/2) * ((N-1)/2)

要使其结果>=N

那么可得:

  • N为偶数:N>=4
  • N为奇数:N>=5

也就是说,只要N>=4,都可被拆分成两个更小的数,使得乘积更大。

那么,能作为乘积的数只有:1,2,3

  • 1*任何数都不能变大,因此排除 1
  • 只能在2 和 3 中选择拆分因数。
    • 我们优先选择3,理由是:
      • 例如 N=6,
      • 3*3>2*2*2
    • 我们选择先拆分为3,能得到选择2更大的结果。

 

总结:

我们对N>=4的数可进行优先拆分出3,循环拆分,

直到拆分不出来3,就其次选择2。

⚠️ 注意,要排除最终拆出个 1 的情况,这样只会削减结果。

例如,4->

先拆分 3 的话,剩下一个 1。因此我们不能选择这种拆法

其次选择拆分 2,再留下个 2。选择这种拆分法。

 

代码参考:

 1 class Solution {
 2 public:
 3     int integerBreak(int n) {
 4         if(n==2) return 1;
 5         if(n==3) return 2;
 6         int product = 1;
 7         while(n>4) {
 8             product *= 3;
 9             n-=3;
10         }
11         product *= n;
12         return product;
13     }
14 };

 

posted @ 2021-04-14 13:56  habibah_chang  阅读(55)  评论(0编辑  收藏  举报