转载: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 }