最優自然數分解問題

2021-09-29 17:17:48 字數 2246 閱讀 6281

time limit:1000ms  memory limit:65535k

total submit:0 accepted:0

type: coding program   language: g++;gcc;vc

問題描述:設n是乙個正整數。

(1)現在將n分解為若干個互不相同的自然數之和,且使這些自然數的乘積最大。

(2)現在將n分解為若干個自然數之和,且使這些自然數的乘積最大。

程式設計任務:對於給定的正整數n,程式設計計算問題(1)和(2)的最優分解的最大乘積。

注意:1. 這裡的自然數不含0但允許為1。

2. 特別地,當整數n無法分解為若干互不相同的加數時,即自身視為單獨的乙個加數,

比如輸入2,問題(1)的解輸出為2。而如果整數n可以分解為若干互不相同的加數時,

不考慮自身為單獨加數的情況,比如4,問題(1)的解輸出為3,而非4。

3. 若干互不相同自然數或若干自然數,這個若干可》=1,也就是可以為1。

只有乙個正整數n(1<=n<=100)。

輸出待解問題(1)和(2)的最大乘積,中間空格相連,這兩個數可能較大請皆用64位整數。

如,輸入n為10,若加數互不相同,則n=2+3+5,此時最大乘積為2*3*5=30。

若加數可相同,則n=2+2+3+3,此時最大乘積為2*2*3*3=36。

10

30 36

分析:

注意無論是(1)還是(2),乘積皆用64位整數表示。

(1)分解為互不相同自然數之和

注意到: 若a+b等於乙個常數,則|a-b|越小,ab就越大。

要使得加數互不相同,又盡可能集中,那加數只能是連續的自然數了。

貪心策略:當n等於1至4時單獨處理。n大於4時,將n分成從2開始的連續的自然數的和。如果最後剩下

乙個數,將此剩餘數在後項優先的方式下均勻地分給前面各項。

(2)分解為若干自然數之和

注意到: 若a+b等於乙個常數,則|a-b|越小,ab就越大。

若 n = m1+m2+...+mk,則 -1 <= (mi-mj) <= 1,(1<=i<=k, 1<=j<=k),

即任意加數的差距不超過正負1。

由於拆分的加數可以相同,任何乙個數拆後乘積總比不拆強,因此拆到極盡,

極盡的加數為3或2,且拆為3比拆為2好,因此優先拆為3。

貪心策略:

極盡拆解,盡可能先將n拆成3,3,3,...,3;若拆成若干3後還有剩餘,則為2,或2和2。

歸納公式如下:

1)max = 3^(n/3) if n(mod 3)等於0

2)max = 4*3^[(n-4)/3] if n(mod 3)等於1

3)max = 2*3^[(n-2)/3] if n(mod 3)等於2

另外此題所涉的64位整數,如何使用?

編譯環境不同,對64位整數的定義和輸入輸出略有不同:

1) gnu gcc/g++ 中long long型別,或unsigned long long,

輸入輸出用cin和cout直接輸出,用scanf和printf也可以的(但本oj系統不支援!)。

long long a;

cin >> a;

cout << a;

也可以使用:(注意一下,本oj系統的gcc/g++不支援64位整數以"%i64d"形式輸出,

但標準gnu gcc是支援如下的,在codeblocks上可以無誤執行)

long long a;

scanf("%i64d",&a);

printf("%i64d",a);

2) vc中用__int64型別,或unsigned __int64

__int64 a;

scanf("%i64d",&a);

printf("%i64d",a);

vc下,64整數不要用cin和cout來輸入輸出,據說vc下64位整數相容不好,會出錯!

大家可測試一下如下程式在vc下是否會出錯?

__int64 a;

cin >> a;

cout << a;

#include #include using namespace std;

long long a[100000]=;

long long n;

long long t1(long long n)

else

最優自然數分解問題

description 問題描述 設n是乙個正整數。1 現在將n分解為若干個互不相同的自然數之和,且使這些自然數的乘積最大。2 現在將n分解為若干個自然數之和,且使這些自然數的乘積最大。程式設計任務 對於給定的正整數n,程式設計計算問題 1 和 2 的最優分解的最大乘積。注意 這裡的自然數不含0但包...

自然數積分解

題目描述 把自然數 分解為若干個自然數之積,輸出方案數。輸入描述 自然數n 1 n 2000000000 輸出描述 方案數。樣例輸入 20 樣例輸出 4 資料範圍及提示 20 可分為 204 52 10 2 2 5 優化前 源 include int n,ans 0 void solve int t...

自然數積分解

題目描述 現需要把自然數n分解為若干個自然數之積,輸出方案數。輸入描述 輸入乙個自然數n 1 n 2000000000 輸出描述 輸出乙個數,表示方案數。樣例輸入 20 樣例輸出 4 資料範圍及提示 樣例可分為 204 5 2 10 2 2 5 優化前 源 include int n,ans 0 v...