正整数分解使得乘积最大问题(转载)

转载:https://blog.csdn.net/xiaoquantouer/article/details/70142739ios

1、问题描述spa

设n是一个正整数。如今要求将n分解为若干个天然数之和,使得天然数的成绩最大。输出这个最大的乘积。.net

要求:code

(1)要求这些天然数互不相同blog

(2)要求这些天然数能够是相同的ci

 

2、问题分析:io

这类题一开始须要咱们手写几个数来看看规律。先作第一问,要求天然数互不相同。从5开始写起,5=2+3,6=2+4,7=3+4,8=3+5,9=2+3+4,10=2+3+5,11=2+4+5class

发现规律以下:stream

(1)尽可能使得元素是连续的。笔试

(2)若是有多出来的,从后往前均匀分配到各个元素。考虑到一种特殊状况,当多出来的数比前面已有元素的个数大1时(好比8的状况),先给已有元素的最大元素加1,而后再均匀分配到每一个元素。

 

下面举个栗子,看看携程实习生招聘笔试的这道题:

题目描述:乘积最大

有一个整数n,将n分解成若干个不一样天然数之和,问如何分解能使这些数的乘积最大,输出这个乘积m。

输入:

一个整数,不超过50

输出

一个整数

样例输入

15

样例输出

144

 1 #include<iostream>
 2 #include<vector>
 3 using namespacestd;  4  
 5 int main(){  6     int num;  7     while(cin>>num){  8         int flag[100] = {0};  9         int k=2; 10         int i=0; 11         while(num >= k){ 12             //从2开始分解,依次分解为2,3,4,5...连续的元素
13             flag[i++] = k; 14             num -= k; 15             k++; 16  } 17         if(num > 0){ 18             //说明有剩余的
19             if(num == flag[i-1]){ 20                 //说明这时候剩余的数正比如已有的元素个数多1,因此要先给最后一个元素加1
21                 flag[i-1]++; 22                 num--; 23  } 24             for(int j=i-1;j>=0 &&num>0;j--){ 25                 flag[j] ++; 26                 num--; 27  } 28  
29  } 30         int result = 1; 31         for(int j = 0;j<i;j++){ 32             result *= flag[j]; 33  } 34         cout<<result<<endl; 35     }//while
36     return 0; 37 }

对于第二问,对于元素能够是相同的

仍然是经过手写几个数查看一下规律:4=2+2,5=2+3,6=3+3,7=3+2+2,8=3+3+2,9=3+3+3。

发现规律以下:

(1)元素不会超过4,由于4=2+2,又能够转化为2的问题,而5=2+3,5<2*3,因此5总能分解成2和3。

(2)尽量多分解出3,而后分解出2,不要分出1。

考虑任意一个数,除以3以后的结果有如下3种:

(1)能被3除断,那么就分解为3+3+...+3的状况便可。例如9=3+3+3。

(2)被3除余1,分解为3+3+...+3+2+2或者3+3+...+3+4的状况,例如10=3+3+2+2

(3)被3除余2,分解为3+3+...+3+2的状况,例如11=3+3+3+2。

 1 #include<iostream>
 2 #include<math.h>
 3 usingnamespace std;  4  
 5 int main(){  6     int num;  7     while(cin>>num){  8         if(num % 3 == 0){   //考虑被3整除的状况
 9             cout<<pow(3,num/3)<<endl; 10             continue; 11  } 12         int flag[100] = {0}; 13         int i=0; 14         while(num != 2 && num != 4){ 15             //若是不能被3整除,那么除3必余1或者2,而余1和4是一样的状况,这里取4是由于这种状况下最后是两个2, 16             //取4就能够直接把4分解为2+2
17             flag[i++]=3; 18             num-=3; 19  } 20         while(num){  //余2和1的状况,余2就是1个2,余1就是2个2,因此前面才会判断是否等于4,这样就能够化为2个2
21             flag[i++] = 2; 22             num-=2; 23  } 24         int result = 1; 25         for(int j=0;j<i;j++){ 26             result *= flag[j]; 27  } 28         cout<<result<<endl; 29     }//while
30     return 0; 31 }
相关文章
相关标签/搜索