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

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=n1++nk.并且 n1××nk是最大乘积。

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


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

对于2.证明,可能一开始看不懂,这里详细再说一下:
因为nk5,所以2nk10,所以3nknk+10,所以3nk9nk


自己写的简单代码实现:

#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]可以递归的定义为

dp[i][j]={1,i=0max(dp[ij][k]j),j00k<j

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

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

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页