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...