【整理自用】清奇思路(三)正解整数分解成不同加数的最大乘积

1.问题描述

n 为一自然数, n 可分解成若干个不同的自然数的和。这样的分法有很多种:比如 n = 10 , n 可按照下述方式分解:

编 号 分解方式举例
1. 10=5+4+1;
2. 10=3+2+3+2;
3. 10=7+3;
4. 10=6+4;
5. 10=7+2+1;
6. 10=6+3+1;
7. ……

在所有这些分法中,各加数乘积最大的为36, (10=3+3+2+2中加数的乘积为3*2*3*2=36)
试编写程序,求各种分解方法中各加数乘积的最大值。

1.1 程序输入输出描述

输入要求:输入只有1行,自然数 n

输出要求:输出也只有1行,所有分解方法中各加数乘积的最大值。

2 清奇思路以及其证明(需要允许加数相同)

因为网页版没找到作者的名字,所以没有贴,如果有同学知道的,我把出处贴完整。

链接:https://www.zhihu.com/question/30071017/answer/47584748
来源:知乎
著作权归作者所有。

把一个正整数N拆成若干正整数只有有限种拆法,所以存在最大乘积。
假设 N = n 1 + + n k . 并且 n 1 × × n k 是最大乘积。

结论:
1. 乘积中不存在1或者超过(包含)5的整数。
2. 选用尽量多的3,直到剩下2或者4时用2;


证明:
1. 显然1不会出现在其中;
2. 如果存在 n k 5 ,则我们将 n k 改为 3 + n k 3 。而 3 × ( n k 3 ) = 3 n k 9 > n k 。所以不存在大于等于5的因子;
3. 4=2+2,乘积不变,不妨设没有因子4;
4. 如果有三个以上的2, 那么 3 × 3 > 2 × 2 × 2 ,所以替换成3乘积更大

对于2.证明,可能一开始看不懂,这里详细再说一下:
因为 n k 5 ,所以 2 n k 10 ,所以 3 n k n k + 10 ,所以 3 n k 9 n k


自己写的简单代码实现:

#include <iostream>
using namespace std;
int pow(int base,int exponent)
{
    //简单实现
    int j=1;
    for (int i = 0;i<exponent;++i)
        j*=base;
    return j;
}
int main() {
    int N=0,factor2=0,factor3=0;
    int multiplication_Max=0;
    cin>>N;
    if(N <= 3)
       cout<<N;
    else 
    {
        int reminder = N % 3;
        switch(reminder)
        {
            case 0: factor3 = N/3;break;
            case 1: 
            {
                factor3 = N/3-1;
                factor2 = 2;
                break;
            }
            case 2:
            {
                factor3 = N/3;
                factor2 = 1;
                break;
            }
        }
        multiplication_Max = pow(3,factor3)*pow(2,factor2);
        cout<<multiplication_Max<<endl;
    }

    return 0;
}

如果至少要分成两个数之和,那么上述代码在开头需要微调:

if(N <= 3)                ====>                 if(N <= 3) 
   cout<<N;               ====>                   cout<<N-1;

3.常规:动态规划的思路

原博客链接:
https://blog.csdn.net/FD1247/article/details/70146062

根据题意,对于一个整数n,必然存在一个整数x,使得从n中分解出整数x可以使其最后获得最大乘积,这要求对n-x的分解也是最优解。我们用dp[i][j]表示从整数i分解出整数j的这种情况下,能达到的最大乘积。那么dp[i][j]可以递归的定义为

d p [ i ] [ j ] = { 1 , i = 0 m a x ( d p [ i j ] [ k ] j ) , j 0 0 k < j

4.不允许加数相同的情况

详细参见:https://blog.csdn.net/xiaoquantouer/article/details/70142739
看完上面的之后,再看这个大神的作品(第三题)会代码上好懂一些:https://blog.csdn.net/flushhip/article/details/79751082
(不过这个本意是用来求允许加数相同的,但是只要稍稍改一下就好)

猜你喜欢

转载自blog.csdn.net/wushuomin/article/details/79950298