日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

整数拆分!

發布時間:2024/4/18 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 整数拆分! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

思路

確定dp數組(dp table)以及下標的含義

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

確定遞推公式

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

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

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

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

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));

也可以這么理解,j * (i - j) 是單純的把整數拆分為兩個數相乘,而j * dp[i - j]是拆分成兩個以及兩個以上的個數相乘。

dp的初始化

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

這里我只初始化dp[2] = 1,從dp[i]的定義來說,拆分數字2,得到的最大乘積是1

確定遍歷順序

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

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

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

所以遍歷順序為:

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

舉例推導dp數組

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

時間復雜度:O(n^2) 空間復雜度:O(n) class Solution { public:int integerBreak(int n) {vector<int> dp(n+1);//因為dp[ii]表示分拆ii得到最大乘積,而dp[0],dp[1]是無意義的dp[2]=1;for(int ii=3;ii<=n;ii++){//以3為起始點開始遞推拆分for(int jj=1;jj<ii;jj++){dp[ii]=max( dp[ii] , max( jj*(ii-jj) , jj*dp[ii-jj] ) );}}return dp[n];} };

總結

以上是生活随笔為你收集整理的整数拆分!的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。