引入問題:
要求將乙個正整數n分成幾個自然數的和,使這些自然數的乘積最大。輸出這個最大值。
分兩種要求:
(1)這些自然數可以相同;
(2)這些自然數互不相同;
(同乙個數n,1的結果應該比2大)。
分析:
(只分析n>=4的情況,因為n<4最大值都是本身)
1.這些自然數可以相同
我們先列幾個數找找規律:
4=2+2、5=3+2、6=3+3、7=3+2+2、8=2+2+2+2、9=3+3+3、10=2+2+2+2+2 …
觀察這些數可以得如下規律:
(1)拆分的自然數不會超過3,因為4可以化為2+2,5可以化為3+2>5,所以所有的數都可以拆為只 有3和2的數;
(2)因為都可以拆除3和2,所有為了使乘積大,應該先盡可能拆除3,而後拆除2,分成1無貢獻;
那麼我們考慮所有的n除以3的情況:
可以被3整除,那麼就將他全部拆為3,如:9=3+3+3;
被3除餘1,那麼可以拆為形如3+3+……+3+4,即3+3+……+3+2+2,如10=3+3+2+2;
被3除餘2,那麼可以拆為形如3+3+……+3+2,如11=3+3+3+2;
實現**:
#include
#include
#include
#include
#include
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int t,n;
intmain()
else
// n為偶數
ans=
pow(
3,cnt3)
*pow(2
,cnt2);}
printf
("%d\n"
,ans);}
return0;
}
2.這些自然數互不相同
也是先寫幾個數找規律:
5=2+3、6=2+4、7=3+4、8=3+5、9=2+3+4、10=2+3+5、11=2+4+5、12=3+4+5、13=3+4+6、
14=2+3+4+5、15=2+3+4+6、16=2+3+5+6、17=2+4+5+6、18=3+4+5+6……
(其實不用列數字,憑以往經驗也應該知道,如果互不相同,這些自然數應該盡量連續,才能使乘積大)
我們可以發現如下規律:
下面對連續自然數做出分析:
我們可以得到形如:2+3+4+5+……k的式子,n是任意整數,我們並不能才好得到連續的自然數,可能多出△x。
對應△x我們可以保證他0<=△x<=k(為什麼一定小於等於k?因為如果大於k,原式應該多加一項變成2+3+4+……+k+k+1)
那麼多出來的△x應該怎麼處理,有上面列的幾個式子的規律,顯然應該從後往前均攤給前k-1個數。
為什麼從後往前呢?應該從前往後或遇到重複的數。
那麼當我們分完△x後,應該會得到兩種式子:
△x=k 3+4+5+6+……+k+(k+2)
△x 顯然我們要求出式子的值,應該借助階乘,階乘中缺失的項,我們除掉就好了,如果數值要求大要求取模,就要用到除法逆元了。求階乘可以用字首積,連續自然數則用字首和,如果時間要求有現在,就用二分來優化,二分找最接近n的字首和。
(這題就用到了逆元,和二分)
題解
正整數分解使得乘積最大問題
一 問題描述 設n是乙個正整數。現在要求將n分解為若干個自然數之和,使得自然數的成績最大。輸出這個最大的乘積。要求 1 要求這些自然數互不相同 2 要求這些自然數可以是相同的 二 問題分析 這類題一開始需要我們手寫幾個數來看看規律。先做第一問,要求自然數互不相同。從5開始寫起,5 2 3,6 2 4...
正整數分解
程式整體思路 分解就是乙個數減1,這個數後面的數加1 一次分解之後 找到最後乙個比1大的元素座標,然後與上一次相比,如果座標發生了偏移,那麼會發生向後偏移,說明又開始有乙個數需要分解,這個時候需要增加乙個元素,該情況下其實就是新出現了2 此時這個座標是2所在的位置 將2分解完畢之後,再繼續找比1大的...
正整數分解演算法
問題 將以正整數n表示成一系列正整數之和.n n1 n2 n3 nk n1 n2 n3 nk 1,k 1 這就是正整數n的乙個劃分,正整數n不同的劃分個數稱為正整數n的劃分數,記作p n 例如 6 有如下11種劃分則p 6 116 5 1 4 2,4 1 1 3 3,3 2 1,3 1 1 1 2 ...