将一个整数拆分使其乘积最大

class Solution
{
public:
    int integerBreak(int n)
    {
        int Max,ThreeIndex,TwoIndex;
        if (n < 4)
        {
            if (n>2)
                return 2;
            return n == 2 ? 1 : 0;
        }
        if (n % 2)
        {
            TwoIndex = ((n - 3) % 6) / 2 ;
            ThreeIndex = (n - 3) / 6 * 2 + 1;
            Max = pow(3, ThreeIndex) * pow(2,TwoIndex);
        }
        else
        {
            TwoIndex = n % 6 / 2;
            ThreeIndex = n / 6 * 2;
            Max = pow(3, ThreeIndex)*pow(2, TwoIndex);
        }
        return Max;
    }
};

最优化问题,尽量都分成3,不足部分就分成2。


对于 n < 4,可以验证其分解成几个正整数的和的乘积是小于 n 的。
对于 n >= 4, 能证明其能分解成几个数的和使得乘积不小于 n。
如果分解成 1 和 n - 1,那么对乘积是没有帮助的,因此,假设 n
分解成 a 和 n - a,2 <= a <= n - 2,那么
     a * (n - a) - n
  = (a - 1) * n - a * a + a - a
  = (a - 1) * (n - a) - a
>= (a - 1) * 2 - a
  = a - 2
>= 0
如果 a, n - a 仍然 >= 4,那么继续分解,直至 a, n - a < 4。因为每次分解都能使乘积
增加,所以最优解必是最终分解结果,也即分解出的数全是 2 或 3 。
(1)
假设 n 是偶数,且分解成 a 个 2 和 b 个 3,即 n = 2 * a + 3 * b,则乘积为 2a * 3b。
注意到 23 < 32 且 2 * 3 = 3 * 2 = 6,所以每 3 个 2 换成 2 个 3 会使乘积更大,因此,
最优方案是分解成 n/6*2 个 3 和 n%6/2 个 2,乘积为 3n/6*2 * 2n%6/2。
(2)
假设 n 是奇数,则一定需要分出一个 3,然后 n - 3 就是偶数。因此最优方案是分解出
(n-3)/6*2+1 个 3 和 (n-3)%6/2 个 2,乘积为 3(n - 3)/6*2+1 * 2(n-3)%6/2。

 
时间: 2024-11-08 21:19:20

将一个整数拆分使其乘积最大的相关文章

算法练习--整数拆分为素数乘积

问题: 输入6 输出 1*2*3 1. build素数表 2. 从素数表按次序取素数,n除素数,如果不能整除,素数表索引++,否则,n/=素数,继续判断 3. 遍历素数表 4. 有限性:素数表需要足够大 ,如果数字非常大,此算法需要改变 JS 实现: function p(n){ if(n<2) {return 0;} if(n == 2){return 1;} for(var i = 2; i < n; i++){ if(n%i == 0){return 0;} } return 1; }

【LeetCode】Maximum Product Subarray 求连续子数组使其乘积最大

Add Date 2014-09-23 Maximum Product Subarray Find the contiguous subarray within an array (containing at least one number) which has the largest product. For example, given the array [2,3,-2,4],the contiguous subarray [2,3] has the largest product = 

LeetCode 343.整数拆分 - JavaScript

题目描述:给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化. 返回你可以获得的最大乘积. 题目分析 题目中"n 至少可以拆分为两个正整数的和",这个条件说明了 n 是大于 1 的整数. 对 7 来说,可以拆成 3+4,最大乘积是 12. 对 8 来说,可以拆成 3+3+2,最大乘积是 18. 解法 1: 动态规划 状态数组dp[i]表示:数字 i 拆分为至少两个正整数之和的最大乘积.为了方便计算,dp 的长度是 n + 1,值初始化为 1. 显然dp[2]等于

整数拆分

将一个整数N拆分成n个连续自然数的和.例如: 15 = 1+2+3+4+5 15 = 4+5+6 15 = 7+8 实现一个函数,打印所有可能,并且统计有多少种方法? 分析过程如下. 对于一个数N, 2个自然数相加:m+(m+1)                                                                                                                  =2m+1 3个自然数相加:(m-1)+m

整数拆分问题的四种解法【转载】

http://blog.csdn.net/u011889952/article/details/44813593 整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,

【转载转载转载!】整数拆分问题的四种解法--尼奥普兰

整数拆分问题的四种解法 原创 2015年04月01日 21:17:09 标签: 算法 / 母函数定理 / 五边形数定理 / acm / 动态规划 整数划分问题是算法中的一个经典命题之一 所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+m3+....+mi;(其中mi为正整数,并且1<=mi<=n),则{m1,m2,m3,....,mi}为n的一个划分. 如果{m1,m2,m3,....,mi}中的最大值不超过m,即max{m1,m2,m3,....,mi} <= m,则称

leetcode 343. 整数拆分:动态规划(c++)

leetcode 343. 整数拆分 分析 状态表示: · dp[i] 表示整数 i 拆分乘积的最大值. 转移方程: · 对于每个数字 i 都进行一遍循环,计算 (i - j) * j,(j <= i - 1),并求其与 dp[i],dp[i - j] * j 的最大值,即:dp[i] = max(dp[i],(i - j) * j,dp[i - j] * j) · 与 dp[i - j] * j 比较是因为 i - j 可能小于 i - j 拆分的乘积. 边界: · 输入的整数 n 大于等于

谭浩强 c程序设计 8.17用递归法将一个整数n转换成字符串。例如,输入486,应输出字符串&quot;486&quot;。n的位数不确定,可以是任意位数的整数。

8.17用递归法将一个整数n转换成字符串.例如,输入486,应输出字符串"486".n的位数不确定,可以是任意位数的整数. #include <stdio.h> char str1[20];int i=0;long n;int main(){        int longToStr(long n);    char *revstr(char *str, int len);    printf("请输入一个整数n:\n");    scanf("

Pollard-Rho大整数拆分模板

随机拆分,简直机智. 关于过程可以看http://wenku.baidu.com/link?url=JPlP8watmyGVDdjgiLpcytC0lazh4Leg3s53WIx1_Pp_Y6DJTC8QkZZqmiDIxvgFePUzFJ1KF1G5xVVAoUZpxdw9GN-S46eVeiJ6Q-zXdei 看完后,觉得随机生成数然后和n计算gcd,可以将随机的次数根号一下.思想很叼. 对于里面说的birthday trick,在执行次数上我怎么看都只能减一半.只是把平均分布,变成了靠近0