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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

剑指Offer:剪绳子(动态规划、贪婪算法)

發布時間:2025/4/16 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 剑指Offer:剪绳子(动态规划、贪婪算法) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題描述

給你一根長度為n的繩子,請把繩子剪成m段(m、n都是整數,n>1并且m>1),每段繩子的長度記為k[0],k[1],…,k[m]。請問k[0]xk[1]x…xk[m]可能的最大乘積是多少?

例如,當繩子的長度是8時,我們把它剪成長度分別為2、3、3的三段,此時得到的最大乘積是18。

輸入描述:
輸入一個數n,意義見題面。(2 <= n <= 60)
輸出描述:
輸出答案。

示例1
輸入 8
輸出 18

解題思路

本題有幾個 可使用動態規劃算法的明顯特征
(1)是求最優解問題,如最大值,最小值;
(2)該問題能夠分解成若干個子問題,并且子問題之間有重疊的更小子問題。

通常按照如下 4 個步驟來 設計一個動態規劃算法
(1)刻畫一個最優解的結構特征;
(2)遞歸地定義最優解的值;
(3)計算最優解的值,通常采用自底向上的方法;
(4)利用計算出的信息構造一個最優解。

以此題為例,

設長度為 n 的繩子剪切后的最大乘積為 f(n),

我們可以將問題看成兩個子問題,即 f(n) = max(f(j)*f(n-j)) ,j 屬于 (1, 2, …, n/2)

也就是說,我們要求 f(n),就只要求將 n 分成 n 、n-j 里面的最優分解就行了。

為什么 j 的邊界是 n/2 呢? --> 因為將一個數分成兩個數,最大的就是 n/2

**假設 n 為 11,**第一刀之后分為了 4-7,而 7 也可能再分成 1-5(7 的最大是 3-4,但過程中還是要比較 1-5 這種情況的),而上一步 4-7 中也需要求長度為 4 的問題的最大值。

可見,各個子問題之間是有重疊的,所以可以先計算小問題,存儲下每個小問題的結果,逐步往上,求得大問題的最優解。

Java 代碼(動態規劃)

import java.lang.*;public class Solution {public int cutRope(int target) {if (target < 2) {return 0;}if (target == 2) {return 1;}if (target == 3) {return 2;}// ropes[i]表示剪i次時的最大乘積int[] ropes = new int[target + 1];ropes[1] = 1;ropes[2] = 2;ropes[3] = 3;int temp = 0;for (int i = 4; i <= target; i++) {int max = 0;// f(i) = max(f(j)*f(n-j)), j屬于(1,2,...,n/2)for (int j = 1; j <= i / 2; j++) {temp = ropes[j] * ropes[i - j];max = Math.max(temp, max);}ropes[i] = max;}return ropes[target];} }

復雜度分析:

  • 時間復雜度:O(n^2)。
  • 空間復雜度:O(n)。

Java 代碼(貪婪算法)

另解(使用貪婪算法):

當 n<5 時,與動態規劃的處理一致;

當n>=5時,盡可能多地剪長度為 3 的繩子,當剩下的繩子長度為 4 時,剪成 2-2;

例如:長度為 10 的繩子, 剪成 3-3-2-2

public int maxProductAfterCutting(int length) {if (length < 2) {return 0;}if (length == 2) {return 1;}if (length == 3) {return 2;}// 盡可能多地剪去長度為3的繩子段int timesOf3 = length / 3;// 當繩子最后剩下的長度為4的時候,不能再剪去長度為3的繩子段// 此時更好的方法是把繩子剪成長度為2的兩段,因為2x2>3x1if (length - timesOf3 * 3 == 1) {timesOf3 -= 1;}int timesOf2 = (length - timesOf3 * 3) / 2;return (int) (Math.pow(3, timesOf3) * Math.pow(2, timesOf2)); }

復雜度分析:

  • 時間復雜度:O(1)。
  • 空間復雜度:O(1)。

雖然貪婪算法的時間復雜度低,但面試官一般都會要求證明

數學證明:

https://www.jianshu.com/p/0a13e48aa4af

總結

以上是生活随笔為你收集整理的剑指Offer:剪绳子(动态规划、贪婪算法)的全部內容,希望文章能夠幫你解決所遇到的問題。

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