贪心算法

upc2337

Problem Description

一个正整数一般可以分为几个互不相同的自然数的和,如3=1+2,4=1+3,5=1+4=2+3,6=1+5=2+4,…。
现在你的任务是将指定的正整数n分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大。

Input

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

Output

第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。第二行是最大的乘积。

Sample Input

10

Sample Output

2 3 5
30
分析:首先我们要找出这些数的规律。(最大乘积)
3=1+2;4=1+3;5=2+3;6=2+4;7=3+4;8=3+5;9=2+3+4;10=2+3+5;11=2+4+5。。。
变为:
3=1+2;
4=1+3;
5=2+3;
6=2+3+1;
7=2+3+2;
8=2+3+3;
9=2+3+4;
10=2+3+4+1;
11=2+3+4+2
。。。
我们会发现,除3和4外,其余的有规律。。。2+3+4+5+6+7+8+9+。。。。。递增单位1的加,知道等于这个数
然而要换成上面乘积最大的数,相比下我们能找出规律:最后以为如果小于等于前一位,则该数向前给1,还有剩继续向前给1,直到为0
这样,最后的数相乘的积最大。。。我们发现10000分解的数不超过150位,可以定义个数组存放分解后的数,在定义一个数组放相乘的
的结果,初始化第一位为1
输入示例:
输入:
10000
输出:
2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 3
2 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 1
09 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 1
29 130 131 132 133 134 135 136 137 138 139 140 141
18981437590761709694285264141107677937281750118953493737972461969961019117597655
33248506853474785138972002542682916216702019230820297304827075914771733278062452
78021157986072528028688788092832111659949431455744000000000000000000000000000000
000

代码如下

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
    int n;
    int i,j,k;
    int sum=0,a;
    int q[1000];
    int num[200];
    cin>>n;
    memset(q,0,sizeof(q));
    q[1]=q[0]=1;
    for(i=2; sum<n; i++)
    {
        num[i]=i;
        sum+=i;
    }
    k=i;
    if(sum>n)
    {
        num[i-1]=num[i-1]-sum+n;
        i=i-1;
        k=k-1;
        int x=i;
        while(num[x])
        {
            num[i--]+=1;
            num[x]--;
        }
    }
    int c=0;
    for(i=2; i<k; i++)
    {
        for(j=1; j<=q[0]; j++)
        {
            q[j]=q[j]*num[i]+c;
            c=q[j]/10;
            q[j]%=10;
        }
        while(c)
        {
            q[j]+=c%10;
            c=c/10;
            q[0]=j;
            j++;
        }

    }
    cout<<num[2];
    for(i=3; i<k; i++)
        cout<<' '<<num[i];
    cout<<endl;
    for(i=q[0]; i>=1; i--)
        cout<<q[i];
    cout<<endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值