正整數分解使得乘積最大問題(轉載)

轉載: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 }
相關文章
相關標籤/搜索