LeetCode第 343 题:整数拆分(C++)

343. 整数拆分 - 力扣(LeetCode)
在这里插入图片描述

这一题可能拆为2个数,3个数甚至更多的时候,因为几何均值总是小于等于算术均值:
a 1 + a 2 + ⋯ + a n n ⩾ a 1 ⋅ a 2 ⋯ ⋯ a n n \frac{a_{1}+a_{2}+\cdots+a_{n}}{n} \geqslant \sqrt[n]{a_{1} \cdot a_{2} \cdots \cdots a_{n}} na1+a2++anna1a2an

当且仅当 a 1 = a 2 = . . . = a n a1=a2=...=an a1=a2=...=an的时候等号成立。所以我们知道若拆分的数量确定, 则均匀拆分时,乘积最大。

以下证明很简单。
假设将 n 等分为 a 份,每份为 x,则有 n = a x n = ax n=ax,乘积为 x a x^a xa,有

x a = x n / x = ( x 1 / x ) n x^a = x^{n/x} = (x^{1/x})^{n} xa=xn/x=(x1/x)n

n 为常数,所以要使乘积最大即求 y = x 1 / x y = x^{1/x} y=x1/x的极大值,直接求导容易得到 x 0 = e x_0 = e x0=e 时取得极大值,而我们的题目要求了 x 必须为整数,最接近 e 的整数是2或3,分别带入2和3可以知道 x = 3 x = 3 x=3时取得最大值。

所以 我们的拆分规则为:

  • 将n尽可能的拆分为多个数字3
  • 最后留下的余数可能如果为2:就不需要拆为两个1了
  • 最后留下的余数如果是1,那么我们应该取出一个3来,将3+1变为2+2,因为(1 * 3 < 2 * 2)
class Solution {
public:
    int integerBreak(int n) {
        if(n <= 3) return n-1;
        // n = a* 3 + b
        int a = n/3, b = n%3; //a为整数部分,b为余数部分
        if(b == 0)  return pow(3,a);
        if(b == 1) return pow(3, a-1)*4;
        return pow(3, a)*2;// b == 2
    }
};

动态规划:

动态规划解拆分整数I[Silver Fox] - 整数拆分 - 力扣(LeetCode)

class Solution {
public:
    int integerBreak(int n) {
      vector<int> a(n+1, 0);
      for(int i = 2; i <= n; ++i){
          for(int j = 1; j < i; ++j){
              a[i] = max(a[i], j*max(i-j, a[i-j]));
          }
      }
      return a[n];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值