您的位置:首页 > 其它

正整数最优分解问题

2013-07-07 17:24 281 查看

一、 题目

   最优分解问题

二、 问题描述

设n是一个正整数。现在要求将n分解为若干互不相同的自然数的和,且使这些自然数的乘积最大。

算法设计:对于给定的正整数n,计算最优分解方案。

数据输入:由文件 input.txt 提供输入数据。文件的第一行是正整数n。

结果输出:将计算出的最大乘积输出到文件output.txt。

输入文件示例

输出文件示例

input.txt

output.txt

10

30

三、 算法基本思想

先对整数分解分析可以发现如下结论:

若 a + b = const,则 |a - b| 越小,a·b越大。

根据原问题的描述,需要将正整数n分解为若干互不相同的自然数的和,同时又要使自然数的乘积最大。当n<4 时对n的分解的乘积是小于n的;当n大于或等于4时,n = 1 + (n-1)因子的乘积也是小于n的,所以n = a + (n-a), 2≤a≤n-2,可以保证乘积大于n,即越分解乘积越大。

因此基于之前发现的结论和上面的分析,可以采用如下贪心策略:将n分成从2开始的连续自然数的和,如果最后剩下一个数,将此数在后项优先的方式下均匀地分给前面各项。

该贪心策略首先保证了正整数所分解出的因子之差的绝对值最小,即|a - b|最小;同时又可以将其分解成尽可能多的因子,且因子的值较大,确保最终所分解的自然数的乘积可以取得最大值。

四、 算法实现(C语言)

/*************************************************
File Name:  optimal_decomposition.cpp
Functions:    最优分解问题求解
将正整数n分解为若干个自然数的和,
使这些自然数的乘积最大。
Author:        Jeccey
Created:     Jeccey
Last Change: 2013-07-03
**************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const int MAX = 51;
int a[MAX - 1];        //记录所分解的自然数

int PIntdecomp(int n);

int main()
{
int n;
char ch;

FILE *fp1, *fp2;
if( (fp1=fopen("input.txt","r")) == NULL){
printf("cannot open file!\n");
exit(0);
}
fscanf(fp1,"%d",&n);

memset(a, 0, MAX*sizeof(int));

if( (fp2=fopen("output.txt","w")) == NULL){
printf("cannot open file!\n");
exit(0);
}
fprintf(fp2,"%d\n",PIntdecomp(n));

return 0;
}

/****************************************************
Function name:    PIntedecomp
Description: 将正整数n分解为若干个自然数的和,
保证所分解自然数的乘积最大并返回。
Arguments:    n (int类型,且n<=437)

Returns:    mresult, int 类型
n所分解的自然数的乘积,返回0表示错误
*****************************************************/
int PIntdecomp(int n)
{
int k,j,mresult;

if (n < 1 )        //非正整数返回0
return 0;
if (n < 5)        //若n<5,结果是其本身
return n;
else{            //若 n>= 5
k = 0;
a[k] = 2;
n -= 2;
/* 贪心策略:先从2开始分成连续自然数的和 */
for (; n > a[k]; ){
a[++k] = a[k-1] + 1;
n -= a[k];
}
/* 如果剩下一个数,将其按后项优先的方式
均匀分给前面各项 */
if (n == a[k]){
a[k]++;
n--;
}
for (j = 0; j < n; j++){
a[k-j]++;
}
/* 计算连乘积 */
for(mresult = 1, j = 0; j <= k; j++){
mresult *= a[j];
}

return mresult;
}
}


View Code

五、关于自然数因子可重复情况

  n<4 —— 乘积<n

  n≥4—— 1. 1和(n-1)→乘积<n,无效;

        2. a和(n-a),且 2≤a≤n-2,分解使乘积增加(可以证明)。

  若因子大于4则继续分解,直至a和(n-a)都小于4。

  因此最终分解结果:全是2或3;又3×3>2×2×2,所以有三个2换成两个3。

最终结果:“M个3”或“M个3和一个2”或“M个三和两个2”

即 R=3^M 或 R=(3^M)×2或 R=(3^M)×4









内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: