luogu p1249 最大乘積

2022-02-15 11:48:51 字數 2145 閱讀 2013

傳送門

乙個正整數一般可以分為幾個互不相同的自然數的和,如 \(3=1+2\),\(4=1+3\),\(5=1+4=2+3\),\(6=1+5=2+4\)。

現在你的任務是將指定的正整數 \(n\) 分解成若干個互不相同的自然數的和,且使這些自然數的乘積最大。

只乙個正整數 \(n\),(\(3 \leq n \leq 10000\))。

第一行是分解方案,相鄰的數之間用乙個空格分開,並且按由小到大的順序。 第二行是最大的乘積。

10
2 3 5

30

此題的關鍵是抓住和同近積大的原理。

和同近積大:兩個數的和一定,差小,積大。

也就是說,假設\(a \ge b\),那麼\((a + 1) \times (b - 1) < a \times b\)。

簡證:\((a + 1) \times (b - 1) = a \times b + b - a - 1\),而既然\(a \ge b\),那麼\(b - a \le 0\)。最後這個算式還有個減一,因此\((a + 1) \times (b - 1) < a \times b\)。

我們考慮在兩個的和同近積大原理上進行擴充套件。因為此題要求所有數字互不相同,我們也想要盡可能多的因數,然後他們還越接近越好。於是如此,我們就可以構造乙個由2開始的自然數數列,然後一直求和,直到這個和大於了\(n\)。

為什麼從\(2\)開始?如果從\(1\)開始的話,\(1\)浪費了這個數和的一塊,卻對整體的積一點用都沒用。血虧!

但是此時和是大於\(n\)的,那麼假設多出來的是\(k\)吧,那麼此時就把值為\(k\)的那項移出去。此時得到的就是正確的數列——

嗎?其實我有乙個問題,就是上述解法是我根據不嚴謹的思路推出來的,我還沒有想好一種嚴格證明的方案,有小夥伴能告訴我嗎?我感激不盡。

哦對了,這道題還需要高精度哦,別忘了,\(n \le 10000\),不開高精見祖宗呢。

本**採用了高精模板。link

/* * @author: crab-in-the-northeast

* @date: 2020-04-02 00:58:54

* @last modified by: crab-in-the-northeast

* @last modified time: 2020-04-02 01:10:27

*/#include #include #include #include #include #include int max(int a,int b)

struct ubigint

ubigint(ull num = 0)

ubigint(std :: string str)

ubigint& operator = (ull num) while(num);

return *this;

} ubigint& operator = (const std :: string& str)

return (*this).clear_zero();

} bool operator < (const ubigint& b) const

bool operator > (const ubigint& b) const

bool operator <= (const ubigint& b) const

bool operator >= (const ubigint& b) const

bool operator == (const ubigint& b) const

bool operator != (const ubigint& b) const

ubigint operator + (const ubigint& b) const

return res.clear_zero();

}ubigint operator - (const ubigint& b) const else last = 0;

res.s.push_back(x);

} return res.clear_zero();

} ubigint operator * (const ubigint& b) const {

std :: vector

P1249 最大乘積

problem p1249 最大乘積 contest luogu url memory limit 125 mb time limit 1000 ms user pannnn include using namespace std 把n分拆成若干個互不相等的自然數的和的分法只有有限種,因而一定存在一...

P1249 最大乘積 洛谷

題目 p1249 最大乘積 分析 一道高精 貪心 乙個數拆的越多乘積會越大,但不要拆出1,這樣浪費了 所以就2,3,4,5,但也不能連續的一直拆,因為可能不夠拆了 所以就可以跳出那個數 把那個數拆給前面的 大概就這樣 上 include using namespace std const int n...

P1249 最大乘積 (數論 貪心)

題目鏈結 題面 題解 從2開始連續幾個自然數的乘積最大。假設我們 2 3 4 k n 剛好成立。我們設ans 2 3 4 k 如果ans n,我們直接輸出乘積即可。如果ans n 1,那我們去掉2,令k 1 如果ans n 1 假設 ans n p,那麼我們去掉p即可。因為需要大數,就用python...