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