算法——整数分解

来源:互联网 发布:西班牙语软件哪个好 编辑:程序博客网 时间:2024/05/23 12:26

一个正整数可以分解成若干自然数之和,请编写一个程序,对于给出的一个正整数(1<=n<=1500),求满足这些自然数的乘积m达到最大。例如:10 = 2 + 2 + 3 + 3,最大乘积为2*2*3*3=36。求任意输入一个自然数,给出有上述条件得到的乘积最大值。

需要证明一下结论:

1. 任意一个大于3的整数n,其自身必然小于他能分解的自然数(除1和n-1外)的乘积。

2. 分离出更多的3的乘积,比分解出更多的2的成绩要大(不能分解出1)

证明1:即是证明x*(a-x) > =a 在a>=4,  x∈(1,a-1),如下:

2.   需要证明,分离出更多的3比分离出更多的2得到的乘积更大,分为奇数和偶数时分别讨论,

在分别将奇数和偶数分为%3=0,1,2这三种情况,一共是6种情况讨论:

偶数时:

 

奇数时:

 

 

  

  

3. 由上面两个证明得出,应尽量分解出多的3,但不能分解出1,得出如果输入n>=4时

n%3=0时,为3^(n/3)

n%3=1时,为3^((n-1-3)/3)*2^2

n%3=2时,为3^((n-2)/3)*2

代码:

#include <iostream>#include <assert.h>#include <string.h>using namespace std;bool metaMulti(char* val, int len, int currentlen, int num, int index, int carry){assert(val && len>0);assert(num >= 0 && num <= 9);if(index >= len) return false;if(index <= currentlen){int f_carry, f_remain; if(val[index]){f_carry = ((val[index] - '0')*num + carry)/10;f_remain = ((val[index] - '0')*num + carry)%10;}else{f_carry = (val[index]*num + carry)/10;f_remain = (val[index]*num + carry)%10;}if(f_remain || f_carry){val[index] = f_remain + '0';}bool ret = metaMulti(val,len,currentlen,3,index+1,f_carry);if(!ret) return false;}else if(carry>0){val[index]=carry+'0';}return true;}bool func(char * val, int len, int num){assert(val && len>0);assert(num >=1 && num <=1500);memset(val,0,len);val[0] = '1';if(num <= 3){val[0] = num + '0';return true;}if(num % 3 == 2){val[0] = (val[0] - '0') * 2 + '0';num -= 2;}else if(num % 3 == 1){val[0] = (val[0] - '0') * 4 + '0';num -= 4;}int n = num/3;for(int i = 0; i < n; i++){int currentlen = (int)strlen(val);metaMulti(val,len,currentlen,3,0,0);}return true;}int main(){int a;cin>>a;char* val = new char[10];func(val, 1024, a);int len = (int)strlen(val);for(int i = 0; i < len; ++i){cout<<val[len-i-1];}printf("\n");return 0;}

  


原创粉丝点击