zoukankan      html  css  js  c++  java
  • GHOJ 427 最大乘积

    题目描述

            一个正整数一般可以分为几个互不相同的自然数的和,如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
    3", 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;
    }
    参考程序
  • 相关阅读:
    《构建之法》前三章读后感--软件工程
    复利计算--web版--总结--软件工程
    利率计算v2.0--web版--软件工程
    <更新日期03-31-2016> 复利计算5.0 <已改进>
    0302随笔
    有限自动机的构造与识别
    评论
    C语言文法
    词法分析 after Coding
    词法分析
  • 原文地址:https://www.cnblogs.com/kcn999/p/10802164.html
Copyright © 2011-2022 走看看