Sword Point Offer Second Edition Interview Question 14: Cut the Rope (java)

Topic description:
Given a rope of length n, please cut the rope into m sections (m, n are integers, n>1 and m>1), the length of each rope is recorded as k[0],k [1],…,k[m]. What is the largest possible product of k[0]* k[1] * ... *k[m]?
For example, when the length of the rope is 8, we cut it into three pieces of length 2, 3, and 3, and the maximum product obtained at this time is 18.

Analysis:
1. Find the optimal solution of a problem;
2. The optimal solution of the overall problem depends on the optimal solution of each sub-problem;
3. Divide the big problem into several small problems, and there are other problems between these small problems. Smaller sub-problems that overlap each other;
4. To avoid repeated computation of sub-problems, we store the optimal solutions of the sub-problems. Analyze problems from the top down, and solve problems from the bottom up.
It can be seen from the above conditions that it is a dynamic programming problem.

Dynamic programming:
1. Define the function f(n) as the maximum value of the product of the lengths of each segment after cutting a rope of length n into several segments.
2. For the first knife, we have n-1 possible choices, and it can be deduced that f(n)=max{f(i)*f(ni)};
3. Obviously, this is a top-to-bottom Recursion, but this recursion has a lot of repeated calculations, so bottom-up dynamic programming is used to save the optimal solution of the sub-problem.
4. Note that the rope cut into ix(ni) and (ni)xi are the same;
5. Note the input n that does not meet the cutting conditions, and the result when the input is 2, 3 lengths, because m>1 is specified in the question.

code show as below:

/*
     * 使用动态规划的思想
     */
    public int fun(int length){
        if(length <= 1)
            return 0;
        if(length == 2)
            return 1;
        if(length == 3)
            return 2;

        int[] products = new int[length + 1];
        products[0] = 0;
        products[1] = 1;
        products[2] = 2;
        products[3] = 3;

        int max = 0;
        for(int i = 4; i <= length; i++){
            max = 0;
            for(int j = 1; j <= i/2; j++){
                if(products[j] * products[i-j] > max)
                    max = products[j] * products[i-j];
            }
            products[i] = max;
        }
        return products[length];
    }

Greedy algorithm:
1. When solving the problem, the greedy algorithm does not consider the overall optimality, and what he makes is a local optimal solution in a certain sense;
2. The greedy strategy selected must have no aftereffects , that is, the previous process of a certain state will not affect the future state, and is only related to the current state;
3. The problem greedy strategy: when n>=5, cut as many ropes of length 3 as possible; when the remaining ropes When the length is 4, cut the rope into two pieces of length 2.

code show as below:

/*
     * 使用贪婪法
     */
    public int fun(int length){
        if(length <= 1)
            return 0;
        if(length == 2)
            return 1;
        if(length == 3)
            return 2;

        //尽可能多的剪长度为3的绳子
        int timesOf3 = length / 3;

        //当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段
        //此时,更好的方法就是把绳子剪成长度为2的两段,因为2x2>1x3
        if(length - timesOf3 * 3 == 1){
            timesOf3--;
        }
        int timesOf2 = (length - timesOf3 * 3) / 2;
        return (int) (Math.pow(3, timesOf3) * Math.pow(2, timesOf2));
    }

Mathematical proof:
1. When n<5, we will find that no matter how we cut, the product product <= n, when n is 4, the maximum product is 2*2=4;
2. When n>=5, it can be Prove that 2(n-2)>n and 3(n-3)>n. And 3(n-3)>=2(n-2). So we should cut as many lengths of rope as possible.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325609054&siteId=291194637