成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

動態(tài)規(guī)劃:整數(shù)拆分,你要怎么拆?

開發(fā) 前端
給定一個正整數(shù) n,將其拆分為至少兩個正整數(shù)的和,并使這些整數(shù)的乘積最大化。返回你可以獲得的最大乘積。

 [[375522]]

整數(shù)拆分

給定一個正整數(shù) n,將其拆分為至少兩個正整數(shù)的和,并使這些整數(shù)的乘積最大化。返回你可以獲得的最大乘積。

示例1:

  • 輸入: 2
  • 輸出: 1
  • 解釋: 2 = 1 + 1, 1 × 1 = 1。

示例 2:

  • 輸入: 10
  • 輸出: 36
  • 解釋: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
  • 說明: 你可以假設 n 不小于 2 且不大于 58。

思路

看到這道題目,都會想拆成兩個呢,還是三個呢,還是四個....

我們來看一下如何使用動規(guī)來解決。

動態(tài)規(guī)劃

動規(guī)五部曲,分析如下:

1.確定dp數(shù)組(dp table)以及下標的含義

dp[i]:分拆數(shù)字i,可以得到的最大乘積為dp[i]。

dp[i]的定義講貫徹整個解題過程,下面哪一步想不懂了,就想想dp[i]究竟表示的是啥!

2.確定遞推公式

可以想 dp[i]最大乘積是怎么得到的呢?

其實可以從1遍歷j,然后有兩種渠道得到dp[i].

一個是j * (i - j) 直接相乘。

一個是j * dp[i - j],相當于是拆分(i - j),對這個拆分不理解的話,可以回想dp數(shù)組的定義。

那有同學問了,j怎么就不拆分呢?

j是從1開始遍歷,拆分j的情況,在遍歷j的過程中其實都計算過了。

那么從1遍歷j,比較(i - j) * j和dp[i - j] * j 取最大的。

遞推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

3.dp的初始化

不少同學應該疑惑,dp[0] dp[1]應該初始化多少呢?

有的題解里會給出dp[0] = 1,dp[1] = 1的初始化,但解釋比較牽強,主要還是因為這么初始化可以把題目過了。

嚴格從dp[i]的定義來說,dp[0] dp[1] 就不應該初始化,也就是沒有意義的數(shù)值。

拆分0和拆分1的最大乘積是多少?

這是無解的。

這里我只初始化dp[2] = 1,從dp[i]的定義來說,拆分數(shù)字2,得到的最大乘積是1,這個沒有任何異議!

確定遍歷順序

確定遍歷順序,先來看看遞歸公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));

dp[i] 是依靠 dp[i - j]的狀態(tài),所以遍歷i一定是從前向后遍歷,先有dp[i - j]再有dp[i]。

枚舉j的時候,是從1開始的。i是從3開始,這樣dp[i - j]就是dp[2]正好可以通過我們初始化的數(shù)值求出來。

所以遍歷順序為:

  1. for (int i = 3; i <= n ; i++) { 
  2.     for (int j = 1; j < i - 1; j++) { 
  3.         dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)); 
  4.     } 

舉例推導dp數(shù)組

舉例當n為10 的時候,dp數(shù)組里的數(shù)值,如下:

343.整數(shù)拆分

以上動規(guī)五部曲分析完畢,C++代碼如下:

  1. class Solution { 
  2. public
  3.     int integerBreak(int n) { 
  4.         vector<int> dp(n + 1); 
  5.         dp[2] = 1; 
  6.         for (int i = 3; i <= n ; i++) { 
  7.             for (int j = 1; j < i - 1; j++) { 
  8.                 dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j)); 
  9.             } 
  10.         } 
  11.         return dp[n]; 
  12.     } 
  13. }; 
  • 時間復雜度:O(n^2)
  • 空間復雜度:O(n)

貪心

本題也可以用貪心,每次拆成n個3,如果剩下是4,則保留4,然后相乘,但是這個結論需要數(shù)學證明其合理性!

我沒有證明,而是直接用了結論。感興趣的同學可以自己再去研究研究數(shù)學證明哈。

給出我的C++代碼如下:

  1. class Solution { 
  2. public
  3.     int integerBreak(int n) { 
  4.         if (n == 2) return 1; 
  5.         if (n == 3) return 2; 
  6.         if (n == 4) return 4; 
  7.         int result = 1; 
  8.         while (n > 4) { 
  9.             result *= 3; 
  10.             n -= 3; 
  11.         } 
  12.         result *= n; 
  13.         return result; 
  14.     } 
  15. }; 
  • 時間復雜度O(n)
  • 空間復雜度O(1)

總結

本題掌握其動規(guī)的方法,就可以了,貪心的解法確實簡單,但需要有數(shù)學證明,如果能自圓其說也是可以的。

其實這道題目的遞推公式并不好想,而且初始化的地方也很有講究,我在寫本題的時候一開始寫的代碼是這樣的:

  1. class Solution { 
  2. public
  3.     int integerBreak(int n) { 
  4.         if (n <= 3) return 1 * (n - 1); 
  5.         vector<int> dp(n + 1, 0); 
  6.         dp[1] = 1; 
  7.         dp[2] = 2; 
  8.         dp[3] = 3; 
  9.         for (int i = 4; i <= n ; i++) { 
  10.             for (int j = 1; j < i - 1; j++) { 
  11.                 dp[i] = max(dp[i], dp[i - j] * dp[j]); 
  12.             } 
  13.         } 
  14.         return dp[n]; 
  15.     } 
  16. }; 

這個代碼也是可以過的!

在解釋遞推公式的時候,也可以解釋通,dp[i] 就等于 拆解i - j的最大乘積 * 拆解j的最大乘積。看起來沒毛病!

但是在解釋初始化的時候,就發(fā)現(xiàn)自相矛盾了,dp[1]為什么一定是1呢?根據(jù)dp[i]的定義,dp[2]也不應該是2啊。

但如果遞歸公式是 dp[i] = max(dp[i], dp[i - j] * dp[j]);,就一定要這么初始化。遞推公式?jīng)]毛病,但初始化解釋不通!

雖然代碼在初始位置有一個判斷if (n <= 3) return 1 * (n - 1);,保證n<=3 結果是正確的,但代碼后面又要給dp[1]賦值1 和 dp[2] 賦值 2,這其實就是自相矛盾的代碼,違背了dp[i]的定義!

我舉這個例子,其實就說做題的嚴謹性,上面這個代碼也可以AC,大體上一看好像也沒有毛病,遞推公式也說得過去,但是僅僅是恰巧過了而已。

本文轉載自微信公眾號「代碼隨想錄」,可以通過以下二維碼關注。轉載本文請聯(lián)系代碼隨想錄公眾號。

 

責任編輯:武曉燕 來源: 代碼隨想錄
相關推薦

2024-11-26 08:09:58

2020-07-07 08:02:33

動態(tài)規(guī)劃緩存枚舉

2021-01-04 08:37:53

動態(tài)規(guī)劃DP

2022-01-10 11:28:55

數(shù)據(jù)結構算法DP入門

2018-07-26 14:50:00

數(shù)據(jù)庫MySQL大表優(yōu)化

2021-02-09 09:55:24

動態(tài)規(guī)劃

2021-01-19 05:46:45

背包數(shù)組容量

2021-01-26 05:39:06

項目模塊代碼

2018-04-04 08:47:16

數(shù)據(jù)中心基礎設施

2021-10-15 09:53:12

工具

2022-09-06 17:58:11

技術雙11

2013-03-31 14:24:21

敏捷開發(fā)Scrum迭代開發(fā)

2009-11-17 09:41:49

程序員的學歷

2018-05-23 00:20:29

2023-01-06 08:42:41

動態(tài)規(guī)劃字符

2019-06-17 09:49:27

裁員失業(yè)品牌

2016-10-25 21:15:46

云計算

2010-03-30 13:24:41

2022-06-30 08:03:13

Prisma數(shù)據(jù)庫工具開源

2015-07-28 14:22:09

BAT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产二区视频 | 欧一区二区 | 亚洲视频在线观看 | 中文字幕日韩欧美一区二区三区 | 欧美性受xxx | 欧美电影一区 | 中文字幕一区二区三 | 一区二区三区不卡视频 | 国产精品久久网 | 国产1区2区在线观看 | 中文字幕在线一区二区三区 | 岛国精品 | 亚洲综合在线播放 | 美女午夜影院 | 久久久精品一区 | 九九色综合 | 在线久草| 天堂在线免费视频 | 亚洲九色| 亚洲成人精品国产 | 欧美不卡一区二区 | 免费观看黄a一级视频 | 在线观看日韩精品视频 | 欧美激情99| 91av视频在线播放 | av手机在线免费观看 | 欧美中文字幕在线 | 成人免费看电影 | 国产免费让你躁在线视频 | 亚洲二区视频 | www.9191.com | 国产精品99久久久久久www | 亚洲美女一区 | 黄色大片在线免费观看 | 日韩一区二区三区在线视频 | 成人在线播放 | 黑人成人网 | 精品日韩一区 | 欧美视频偷拍 | 精品一二三区视频 | 美女视频一区二区三区 |