1. 程式人生 > >最優分解(貪心)

最優分解(貪心)

Description:設n是一個正整數。現要求將n分解為若干個自然數的和,且使這些自然數的乘積最大。對於給定的正整數n,程式設計計算最優分解方案。

Sample Input:

10

Sample Output:

36

analysis:

若 a + b = c,則 | a – b | 越小,a × b 越大。根據原問題的描述,需要將正整數 n 分解為若干互不相同的自然數的和,同時又要使自然數的乘積最大。當 n < 4 時對 n 的分解的乘積是小於 n 的;當 n 大於或等於 4 時,n = 1 + ( n – 1 ) 因子的乘積也是小於 n 的,所以 n = a + ( n – a ),2 ≤ a ≤ n - 2,可以保證乘積大於 n,即越分解乘積越大。

將 n 分成從 2 開始的連續自然數的和,如果最後剩下一個數,將此數在後項優先的方式下均勻地分給前面各項,確保最終所分解的自然數的乘積可以取得最大值。

在分解過程中,主要有以下2種情況:

1.當前餘數與當前分解出的最後一位數字值相等(如:13 = 2 + 3 + 4 + 4),則最終分解結果必定從3開始(詳解於analysis第一段);

2.當前餘數與當前分解出的最後一位數字值不等(如:10 = 2 + 3 + 4 + 1),則最終分解結果必定從2開始(詳解於analysis第一段);

/* 
 * ===================================================================================== 
 * 
 *       Filename:  MulMax.c 
 * 
 *    Description:   
 * 
 *        Version:  1.0 
 *        Created:  2015年12月10日 22時33分14秒 
 *       Revision:  none 
 *       Compiler:  gcc 
 * 
 *         Author:  lafee, 
[email protected]
* Company: Class 1301 of Software Engineering * * ===================================================================================== */ #include <stdio.h> int MulMax( int num ) { int i = 1 , j; int mul = 1 ; while( num > i ) { //當迴圈結束,num為當前餘數 i++ ; num -= i ; } if( num == i ) { //當前餘數與最後一位分解出的數字相同,如:13 = 2 + 3 + 4(i) + 4(num) for( j = 3 ; j < i + 3 ; j++ ) { //最終分解的結果必定從3開始且最後一位數與倒數第二位數之差為2,如:13 = 3 + 4 + 6 if ( j == i + 1 ) continue ; mul *= j ; } } else { for( j = 2 ; j < i + 2 ; j++ ){ //最終分解的結果從2開始 if( j == i - num + 1 ) continue ; mul *= j ; } } return mul ; } int main() { int num ; scanf( "%d", &num ) ; printf( "MUl = %d\n", MulMax( num ) ) ; return 0; }