最大乘积
题目描述
一个正整数一般可以分为几个互不相同的自然数的和,如 3 = 1 + 2 3=1+2 3=1+2, 4 = 1 + 3 4=1+3 4=1+3, 5 = 1 + 4 = 2 + 3 5=1+4=2+3 5=1+4=2+3, 6 = 1 + 5 = 2 + 4 6=1+5=2+4 6=1+5=2+4。
现在你的任务是将指定的正整数 n n n 分解成若干个互不相同的自然数(也可以不分解,就是这个数字本身)的和,且使这些自然数的乘积最大。
输入格式
只一个正整数 n n n,( 3 ≤ n ≤ 10000 3 \leq n \leq 10000 3≤n≤10000)。
输出格式
第一行是分解方案,相邻的数之间用一个空格分开,并且按由小到大的顺序。
第二行是最大的乘积。
样例 #1
样例输入 #1
10
样例输出 #1
2 3 5
30
问题链接: P1249 最大乘积
问题分析: 大数问题,不解释。
参考链接: POJ NOI MATH-7652 乘积最大的拆分
题记: (略)
AC的C++语言程序如下:
/* P1249 最大乘积 */
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdio>
using namespace std;
const int R = 10000; // 万进制
const int N = sqrt(2 * 10000) + 3; // Sn=n(n+1)/2
int ans[N];
int p[2500];
void mul(int n, int a[])
{
int len = 1;
memset(p, 0, sizeof p);
p[0] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 0; j < len; j++)
p[j] *= a[i];
int carry = 0;
for (int j = 0; j < len; j++) {
p[j] += carry;
carry = p[j] / R;
p[j] %= R;
}
if (carry) p[len++] = carry;
}
while (p[len - 1] == 0 && len > 1) len--;
printf("%d", p[len - 1]);
len -= 2;
while (len >= 0) printf("%04d", p[len--]);
printf("\n");
}
int main()
{
int n;
scanf("%d", &n);
int i = 2;
while (n >= i)
ans[i] = i, n -= i, i++;
int j = --i;
while (n > 0 && j >= 2)
ans[j--]++, n--;
if (n) ans [i]++;
for (j = 2; j <= i; j++) {
if (j > 2) printf(" ");
printf("%d", ans[j]);
}
printf("\n");
mul(i, ans);
return 0;
}