题目大意
要求将n写成若干个正整数之和,并且使这些正整数的乘积最大,保留小数点前一百位。
思路
可以先分类讨论。
发现拆成三的方法最优,也可以证明:
拆成2:
(
n
−
2
)
×
2
=
2
n
−
4
(n-2)×2=2n-4
(n−2)×2=2n−4
拆成3:
(
n
−
3
)
×
3
=
3
n
−
9
(n-3)×3=3n-9
(n−3)×3=3n−9
相差:
∵
3
n
−
9
−
(
2
n
−
4
)
=
n
−
5
\because 3n-9-(2n-4)=n-5
∵3n−9−(2n−4)=n−5
∴ n > 5 , 拆三更好 \therefore n>5,拆三更好 ∴n>5,拆三更好
我们继续看7。
7
→
2
×
2
×
3
7 →2×2×3
7→2×2×3
1
×
3
×
3
\qquad \xcancel {1×3×3}
1×3×3
我们先拆一个3:
7
=
3
×
4
7=3×4
7=3×4
此时按照最优拆法,4应该拆成
2
×
2
2×2
2×2。
也能推出
8
=
2
×
3
×
3
8=2×3×3
8=2×3×3
所以%3余1则将余数1和一个三并成两个2,其他正常拆
代码如下:
#include <iostream>
using namespace std;
int m, p3, p;//p3是乘三的个数,p是多余乘
int n[10001] = { 0, 1 };
int main() {
cin >> m;
if (m % 3 == 0)
p3 = m / 3;
if (m % 3 == 1)
p3 = m / 3 - 1, p = 4;
if (m % 3 == 2)
p3 = m / 3, p = 2;
int x = 0, size = 1;
for (int i = 1; i <= p3; i++) {
x = 0;
for (int j = 1; j <= size; j++) {
n[j] *= 3, n[j] += x;
x = n[j] / 10;
n[j] %= 10;
}
if (x)
size++, n[size] = x;
}//高精乘单精
x = 0;
if (p != 0)//为了避免输出零
for (int i = 1; i <= size; i++) {
n[i] *= p, n[i] += x;
x = n[i] / 10;
n[i] %= 10;
}
if (x)
size++, n[size] = x;
cout << size << endl;
if (size > 100)
for (int i = size; i >= size - 99; i--) cout << n[i];
else
for (int i = size; i >= 1; i--) cout << n[i];
}