【题解】最大乘积

题目描述

        一个正整数一般可以分为几个互不相同的自然数的和,如3=1+2,4=1+3,5=1+4=2+3,6=1+5=2+4,...。

        现在你的任务是将指定的正整数n分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。

输入格式

        一行,只一个正整数n(3<n≤10000)。

输出格式

        第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序排列;

        第二行是最大的乘积。

输入样例

10

输出样例

2 3 5

30

 

题解

         容易想到贪心策略:(1)不分解出$1$;(2)让分解出的数尽可能相互接近。

         那我们可以从$2$开始一直分解,直到无法继续分解了。

         假设我们已经分解出了$2$~$k-1$,且$n$被分解到只剩下$m$,那么我们可以不分解出$k-m$,然后让$m$和$k-m$的和再形成一个分解出来的数,这样就可以把$n$分解完且能满足贪心策略(2)。

#include <iostream>
#define MAXN 10000

using namespace std;

int n;
int a[100];
int sa = 1;
bool b[MAXN];
int maxb = 1;

int main()
{
    cin >> n;
    if(n == 4) return cout << "1 3\n3", 0;
    a[0] = 1;
    while(n >= maxb + 1)
    {
        b[++maxb] = 1;
        n -= maxb;
    }
    if(n)
    {
        b[maxb - n + 1] = 0;
        b[++maxb] = 1;
        n = 0;
    }
    for(register int op = 0, i = 2; i <= maxb; i++) if(b[i])
    {
        if(op++) cout << " ";
        cout << i;
        for(register int j = 0; j < sa; j++)
        {
            a[j] *= i;
        }
        for(register int j = 0; j < sa; j++)
        {
            if(a[j] > 9)
            {
                if(j + 1 == sa) sa++;
                a[j + 1] += a[j] / 10;
                a[j] %= 10;
            }
        }
    }
    cout << endl;
    while(sa--)
    {
        cout << a[sa];
    }
    return 0;
}
参考程序

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10802164.html
今日推荐