给你一个正整数N,现在要把这个正整数拆分成若干个正整数,使得它们的和等于N,并且使得它们的积最大。也就是说把一个正整数N,拆分成k个正整数bi (i>=1&&i<=k) 使得b1+b2+??+bk=N,并且b1*b2*??*bk最大(如果有多个拆分方案使得最大值相等,则选择k最大的方案)。
例如:
拆分方案 乘积
4 = 1 + 1 + 1 + 1 1 * 1 * 1 * 1 = 1
4 = 1 + 1 + 2 1 * 1 * 2 = 2
4 = 1 + 3 1 * 3 = 3
4 = 2 + 2 2 * 2 = 4
4 = 4 4 = 4
此时有两种拆分方案的乘积都达到最大值4,此时应该选择4 = 2 + 2这种方案。
现在给你一个正整数N (N>0&&N<=10000),请你输出那个满足题意的拆分方案。
输入格式
此题有多组测试数据,每个测试数据单独站一行,当输入为0时,结束。
输出格式
每个测试数据的输出单独占一行,在这一行中,把拆分方案中的数按从小到大的顺序输出,相邻两个数用一个空格分开。
样例输入
1 2 3 4 5 6 7 8 0
样例输出
1 2 3 2 2 2 3 3 3 2 2 3 2 3 3
/*如果不在乎是否为整数的话,那么把每份平均分为e(2.71828459045...)时,所得到的乘积是最大的,
如果要是整数的话,那么就选尽可能地靠近e的整数即可,比如3。
具体证明请参见 http://blog.csdn.net/pathuang68/article/details/6606605
若n<=3,无需拆分,它本身就是最大的;
n==4,拆分为2,2;
若n>4, 将n表示成 3k+r(k>0, 0< = r <3)的形式,r为余数。
case 1: r=0,可将n拆成k个3.
case 2: r=1,将n拆成k-1个3,和2个2.
case 3: r=2,将n拆成k个3,和1个2.*/
#include <stdio.h>
int n;
void split(int n){
if(n<=3)
printf("%d\n",n);
else if(n==4) printf("2 2\n");
else{
int i,k,r;
k=n/3,r=n%3;
if(r==1){k--;r+=3;}
if(r==2) printf("2 ");
if(r==4)
printf("2 2 ");
for(i=0;i<k;i++){
if(i==0)printf("3");
else printf(" 3");
}
printf("\n");
}
}
int main(){
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
split(n);
}
return 0;
}