最优分解问题
设n是一个正整数,现在要求将n分解为若干个互不相同的自然数的和,使这些自然数的乘积最大。
输入 10
输出 30
(被分解为5 2 3)
分析:
1、若a+b等于一个常数,则|a-b|越小,a*b就越大。要使得加数互不相同,又尽可能集中,那加数只能是连续的自然数了。
2、一个数能分解,分解后乘积会比之前更大。如6,分成2和4,乘积8>6
3、如图,按理说,下一步再从diff中分解出6,但是diff<p[3],无法分解。要把diff均匀(每次加1)地加到前面每一项,并且后项优先原则。
#include<stdio.h>
int main(){
int n; //被分解的数
printf("n的值:\n");
scanf("%d",&n);
int p[n/2]; //接收n分解成的自然数
int i,j,num=0;
int s=1;
p[0]=2;
int diff=n-2;
for(i=0;i<n/2;i++){
p[i+1]=p[i]+1;
diff-=p[i+1];
if(diff<=p[i+1]){
break;
}
}
num=i+2;//n=15,i=2时diff<p[i+1],退出循环,i仍然为2,但实际呢,
//有p[0],p[1],p[2],p[3]四个元素,所以再加2 ,得到数组的个数
while(diff!=0){
//此时diff为1,还需要把它加到前面的各个数上
//原则:后项优先,所以应该给p[3]加上
j=num;
p[j-1]++;
diff--;
j--;
if(j==0) //因为循环赋值
j=num;
}
printf("%d被分解为:\n",n);
for(i=0;i<num;i++)
{
s*=p[i];
printf("%d\t",p[i]);
}
printf("\n乘积最大为:");
printf("%d\n",s);
return 0;
}