• 【a602】最大乘积


    Time Limit: 1 second
    Memory Limit: 32 MB

    【问题描述】

    一个正整数一般可以分为几个互不相同的自然数的,如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
    

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=a602

    【题解】

    注意这里是说分解成若干个不同的;不能有相同的;
    首先考虑分解后的情况.
    假设一个数字为h;
    分解成两个部分a,h-a;
    然后考虑它们的乘积与h的大小关系
    令f(a)=a*(h-a)-h
    =a*h-a*a-h
    =(a-1)*h-a*a
    这里让a< h/2(因为要不同嘛,就假设a< h-a呗->a< h/2)
    则h>2*a
    则f(a)>(a-1)*2a-a*a
    ->f(a)>a*a-2*a;
    ->f(a)>a(a-2);
    也就是说如果a>=2的话
    f(a)>a(a-2)>=0
    即f(a)>0
    也即a*(h-a)>h
    所以如果分成的若干个不同的数,它们都大于1的话,那么分成的乘积肯定比原来的大;
    这里;再展示一个事实;
    设h=2*s
    假设他分成了
    s-1和s+1
    那么乘积为s^2-1
    如果分成了
    s-2和s+2
    那么乘积为s^2-4
    也就是说分成的两个数a,b
    它们的差的绝对值越小;
    它们的乘积就相应地越大;
    这样我们可以先选取连续的自然数
    2,3,4,5….x
    这里(2+x)*(x-1)/2<=n
    然后令temp = n-(2+x)*(x-1)/2
    如果tmep=0
    那么因为是连续的自然数,那么它们的差肯定是最小的;(差都是1);
    则直接输出2,3,4..x就好
    如果temp>0;
    那么就把temp平均地分配到前面的数字里面去;
    当然你要从后往前一个一个地分配
    比如
    n=13
    2 3 4
    13-(2+3+4)=4
    则分配两个1给4,然后2和3分别给它们分配一个1(在平均的情况下尽量先分配后面的)
    ->3 4 5
    这样就能保证差的绝对值相对地小;
    最后的成绩也就越大;
    (在数学推导上的贪心?)
    最后数字很大要写个高精度乘单精度;
    (n=3和4的情况特判一下)

    【完整代码】

    #include <cstdio>
    #include <iostream>
    #include <vector>
    using namespace std;
    #define pb push_back
    #define LL long long
    
    const int MAXN = 100;
    
    int n,now;
    LL a[1000];
    vector <LL> v;
    
    int main()
    {
        scanf("%d",&n);
        if (n==3 || n==4)
        {
            printf("%d %d
    %d",1,n-1,n-1);
            return 0;
        }
        v.pb(2);n-=2;now=3;
        while (n >= now)
        {
            n-=now;
            v.pb(now);
            now++;
        }
        now = v.size()-1;
        while (n)
        {
            v[now]++;
            now--;
            n--;
            if (now==-1)
                now = v.size()-1;
        }
        a[1] = 1;
        int le = 1,len = v.size();
        for (int i = 0;i <= len-1;i++)
        {
            int x = 0;
            for (int j = 1;j <= le;j++)
            {
                a[j] = a[j]*v[i] + x;
                x = a[j]/10;
                a[j]%=10;
            }
            while (x>0)
            {
                le++;
                a[le] = x;
                x = a[le]/10;
                a[le]%=10;
            }
        }
        for (int i = 0;i <= len-1;i++)
        {
            printf("%I64d",v[i]);
            if (i==len-1)
                puts("");
            else
                putchar(' ');
        }
        for (int i = le;i >= 1;i--)
            printf("%I64d",a[i]);
        return 0;
    }
    
  • 相关阅读:
    FastDFS分布式文件系统
    Nginx负载均衡
    Linux系统:第六章:Linux服务
    libphp5.so可能遇到的问题(转摘)
    apache和tomcat的关系
    linux有些sh文件,为什么要用 ./ 来执行
    Linux上安装apache
    解决centos6系统上python3—flask模块的安装问题
    常见的消息队列中间件介绍
    Linux上部署Tomcat+Nginx负载均衡
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626684.html
Copyright © 2020-2023  润新知