贪心算法,n分解成自然数只和,求最大成绩问题

本文介绍了一种算法,用于找到一个整数n分解为若干正整数之和时,这些正整数乘积最大的方案。文章通过数学证明阐述了算法的设计原理,并给出了C语言实现的源代码及运行结果。

1.软件平台:ubuntu


2. 算法设计与分析
1.对于 n <= 4,可以验证其分解成几个正整数的和的乘积是小于 n 的。
2.对于 n >4, 能证明其能分解成几个数的和使得乘积不小于 n。如果分解成 1 和 n - 1,那么对乘积是没有帮助的,因此,假设 n分解成 a 和 n - a,2 <= a <= n - 2.如果 a, n - a 仍然 > 4,那么继续分解,直至 a, n - a <= 4。因为每次分解都能使乘积增加,所以最优解必是最终分解结果,也即分解出的数全是 2 或 3 .
3.若1作因数,则显然乘积不会最大。把m分拆成若干个互不相等的自然数的和,因数个数越多,乘积越大。为了使因数个数尽可能地多,我们把m分成2+3…+n直到和大于等于m。若和比m大1,则因数个数至少减少1个,为了使乘积最大,应去掉最小的2,并将最后一个数(最大)加上1。若和比m大k(k≠1),则去掉等于k的那个数,便可使乘积最大。

3.源代码

#include<stdio.h>

#include<stdlib.h>

#include<fcntl.h>

#include<math.h>

#include<time.h>

int BestDecomepose(int *a)//求自然乘机的最大和

{

int i,j;

int d,r=1,sum=0;

for(i=2;;i++)

{

sum+=i;

d=(sum-*a);

if(d>=0)

break;

}

printf("组成最大成绩的自然数分别是:\n");

if(d==1)

{

for(j=3;j<i;j++)

{

r*=j;

printf("%d ",j);

}

++i;

printf("%d \n",i);

r*=i;

}

else

{

for(j=2;j<=i;j++)

{

if(j==d) //如果j和d相等,就不执行continue下面的语句了

continue;

r*=j;

printf("%d ",j);

}

 printf("\n");

}

return r; 

}

main()

{

FILE *fp,*fp1;

int a,max;

fp=fopen("input1.txt","wt");//将随机数写入文件

if(fp==NULL)

{

printf("Conot open the file!");

exit(0);

}

srand((int)time(0));//避免和上次取得数相同

a=1+(int)(25.0*rand()/(RAND_MAX+1.0));//取随机数

fprintf(fp,"%d",a);

printf("Input1.txt:\n");

printf("%d\n",a);

fclose(fp);

if(a>4)//当输入的数大于4的情况

{

max=BestDecomepose(&a);

fp1=fopen("output1.txt","wt");//将大于4的结果写入文件

        if(fp1==NULL)

         {

                 printf("Conot open the file!");

                 exit(0);

         }

fprintf(fp1,"%d",max);

fclose(fp1);

}

else

{

fp1=fopen("output1.txt","wt");//将小于等于4的结果写入文件

                if(fp1==NULL)

                {

                        printf("Conot open the file!");

                        exit(0);

                }

                fprintf(fp1,"%d",a-1);

fclose(fp1);

}

       printf("output1.txt:\n"); //输出文件里的类容

               fp1=fopen("output1.txt","rt");

               if(fp1==NULL)

                {

                        printf("Conot open the file!");

                        exit(0);

                }

                fscanf(fp1,"%d",&max);

printf("%d\n",max);

                fclose(fp1);

 

}

4.运行结果




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值