Sword Finger Offer 14- I. Cut the Rope-Dynamic Programming and Greedy

Cut the rope

Give you a rope of length n, please cut the rope into m segments of integer length (m and n are integers, n>1 and m>1), the length of each segment of rope is recorded as k[0],k [1]...k[m-1]. What is the maximum possible product of k[0] k[1] …*k[m-1]? For example, when the length of the rope is 8, we cut it into three pieces with lengths of 2, 3, and 3. The maximum product obtained at this time is 18.

Example 1:
Input: 2
Output: 1
Explanation: 2 = 1 + 1, 1 × 1 = 1

Example 2:
Input: 10
Output: 36
Explanation: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

Source: LeetCode
Link: Click to jump to https://leetcode-cn.com/problems/jian-sheng-zi-lcof


Dynamic programming

Problem-solving ideas:

  1. We want to ask for the maximum product of the rope of length n after being cut, which can be transferred from the previous rope that is smaller than n
  2. Use a dp array to record the maximum product of a rope with a length of 0 to n after being cut, that is, dp[i] represents the maximum product of a rope with a length of i after being cut into m segments, and initialize dp[2] = 1
  3. We first cut the first section of the rope (length is j), if only the length is 1, there is no gain to the final product, so start from the length of 2.
  4. After cutting the first section, the remaining length (i-j) can be cut or not. If it is not cut, the length product is j * (i-j); if it is cut, the length product is j * dp[i-j]. Take the maximum of the two max(j * (i-j), j * dp[i-j])
  5. The interval for the length j of the first segment is [2,i), and the maximum value is taken for all j different cases, so the final transfer equation of dp[i] is dp[i] = max(dp[i], max( j * (i-j), j * dp[i-j]))
  6. Finally return to dp[n]
class Solution {
    
    
    //动态规划
    public int cuttingRope(int n) {
    
    
        int[] dp = new int[n+1];   //从长度为0到长度为n,一共有n+1个长度
        int i;  //i代表长度为i的线
        int j;  //j代表剪掉线的长度
        dp[2] = 1;  //当线长度为2的时候,最大的乘积肯定是1,d[1],d[0]为创建数组的默认值0
        //i从3开始,因为小于3的长度的最大乘积很明确,一直遍历到最大的长度,得到dp[i]长度为i的绳子剪成m段后的最大乘积
        for(i = 3; i < dp.length; i++) {
    
    
            //剪掉的长度为j,一直遍历到该绳子的最大长度
            for(j = 2; j < i; j++) {
    
    
                int tmp = Math.max(j*(i-j),j*dp[i-j]);  //剪掉j后的长度为i-j,所以乘积就为j*(i-j)
                //如果剪掉j后再要继续剪,那么就相当于再从i-j中得出最大乘积,i-j绳的最大乘积就为之前算出来的dp[i-j]
                //所以最后直接判断 只剪断j的乘积 和 剪断j后继续再剪的乘积 的最大值就可以
                dp[i] = Math.max(dp[i],tmp);    //比较前一个剪断j后的最大乘积 和 现在剪断j后的最大乘积,因为j是一直变化的
            }
        }
        //最后只用返回题目需要长度为n的绳子 的最大乘积
        return dp[n];
    }
}

how are you

The core idea is: divide the rope as much as possibleA short section of length 3, So that the product is the largest

Proceed as follows:

  1. If n == 2, return 1. If n == 3, return 2. If two can be combined into n less than 4, return n-1
  2. If n == 4, return 4
  3. If n> 4, divide it into as many segments of length 3 as possible, subtract 3 from the length of each loop, and multiply the product res by 3; at the end, multiply the last segment less than or equal to 4
  4. The above 2 and 3 can be combined
class Solution {
    
    
    public int cuttingRope(int n) {
    
    
        if(n < 4){
    
    
            return n - 1;
        }
        int res = 1;
        while(n > 4){
    
    
            res *= 3;
            n -= 3;
        }
        return res * n;
    }
}

Guess you like

Origin blog.csdn.net/starry1441/article/details/115009014