最大乘积

题目描述

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

有趣的高精度

对于一个数,我们拆互不相同的个数越多,就应该越大

比如样例

divide   mul

2 8   16

2 3 5   30

但也有特例,当n<5

2,3,4的拆分还不如自己本身

 

#include<stdio.h>
const int MX=10001;
int n,la,lb,len,ser[MX],a[MX],b[MX],c[MX];

void mul() 
{
    int lc;
    for(int i=1;i<=la;++i) 
        for(int j=1;j<=lb;++j) {
            c[i+j-1]+=a[i]*b[j];
            c[i+j]+=c[i+j-1]/10;
            c[i+j-1]%=10;
        }
    if(c[la+lb]) lc=la+lb;
    else lc=la+lb-1;
    for(int i=1;i<=lc;++i) a[i]=c[i],c[i]=0;
    la=lc;
}

void div()
{
    int i=2;
    while(n>0) {
        if(n<=i) ser[i-1]=n;
        else ser[i-1]=i;
        n-=i;
        ++i;
    }
    len=i-2;
    if(ser[len]<=ser[len-1]) {
        int w=len;
        while(ser[len]) 
        {
            w--;
            if(w==0) w=len-1;
            ser[w]++;
            ser[len]--;
        }
        len--;
    }
    a[1]=ser[1];
    la=1;
    for(int j=2;j<=len;++j) 
    {
        lb=0;
        int t=ser[j];
        while(t) {
            b[++lb]=t%10;
            t/=10;
        }
        mul();
    }
}

int main() 
{
    scanf("%d",&n);
    if(n<=4) {
        printf("%d",n);
        return 0;
    }
    div();
    for(int i=1;i<=len;++i) printf("%d ",ser[i]);
    printf("\n");
    for(int i=la;i;--i) printf("%d",a[i]);
    return 0;
}

 

posted @ 2018-10-07 10:32  qseer  阅读(236)  评论(0编辑  收藏  举报