问题描述:
设n是一个正整数。现在要求将n分解为若干不相同的自然数的和,且使这些自然数的乘积最大。
算法设计:
对于给定的正整数n,计算最优分解方案
数据输入:
由文件input.txt提供输入数据。文件的第1行是正整数n。
结果输出:
将计算的最大乘积输出到文件output.txt。
输入文件示例 输出文件示例
Input.txt output.txt
10 30
设计思路:
根据学过的数学知识,我们知道要分解后的乘积最大,应该是(1/2)的平方,即以前学过的正方形的面积肯定比同等周长的长方体大,所以应该将要分解的数分解为越接近的数字越好,分解的越多越好,而如果分解一个1的话对结果无影响,所以从2开始分解,每次加1,直到分解到剩下的数小于等于分解的最后一个数字为止。
例如分解10=2+3+4,剩下1<4,然后为了使前面的不重复,因此把1加到4上。
分解11=2+3+4,剩下2,加到4,3上,依次类推。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
/
/最优分解
int OptimalDecomposition (int n)
{
int before_n = n;
//如果要分解的数小于等于4,那么最终乘积为n-1
if (n <= 4)
{
return n - 1;
}
//如果大于4
//从2开始分解
int i = 0;
int k = 2;
int a[20] = { 0 };
while (n>k)
{
a[i++] = k;
n -= k;
k++;
}
//如果最后剩下的数字等于最后一个数字
if (n == a[i - 1])
{
n--;
a[i - 1]++;
}
//对前面的数字从后向前+1
for (int j = 0; j < n; j++)
{
a[i - 1 - j]++;
}
//求乘积
int maxProduct = 1;
for (int j = 0; j < i ; j++)
{
maxProduct *= a[j];
}
//输出最优分解方式和乘积
printf ( "%d的最优分解方式为:%d" ,before_n,a[0]);
for (int j = 1; j < i; j++)
{
printf ( "*%d" , a[j] );
}
printf ( "=%d\n" , maxProduct );
return maxProduct;
}
int main ()
{
FILE*f1 = fopen ( "D:/学习/大三上/算法设计与分析/实验三报告+附件/input(2).TXT" , "r" );
if (f1 == NULL)
{
printf ( "打开文件错误" );
return 0;
}
int n = 0;
fscanf ( f1 , "%d" , &n );
fclose ( f1 );
FILE*f2 = fopen ( "D:/学习/大三上/算法设计与分析/实验三报告+附件/output(2).TXT" , "w" );
int maxProduct = OptimalDecomposition ( n );
fprintf ( f2 , "%d" , maxProduct );
fclose ( f2 );
return 0;
}
运行结果: