【Sword Finger Offer】 —— Dynamic programming and greedy algorithm derived from the rope cutting problem

Topic requirements

Give you a rope of length n, please cut the rope into m lengths of integer length (m and n are integers, n> 1 and m> 1), the length of each rope is denoted as k [0], k [1], ..., k [m]. What is the maximum possible product of k [0] xk [1] x ... xk [m]? For example, when the length of the rope is 8, we cut it into three sections of length 2, 3, and 3, respectively, and the maximum product obtained at this time is 18.

1. Dynamic programming analysis and solution

First, let's take a look at dynamic programming. What general problems are solved using dynamic programming?
If the problem seeks the optimal solution to a problem, and the problem can be decomposed into several sub-problems, and there are smaller sub-problems that overlap.

Features:

  1. The optimal solution of the overall problem is the optimal solution that depends on each problem
  2. Break down big problems into several small problems, and there are smaller sub-problems that overlap each other
  3. Analyze the problem from top to bottom, and solve the problem from bottom to top

Then, using the idea of ​​dynamic programming, let's think about how to cut the rope.
Insert picture description here
Therefore, we know that f (1) = 1, f (2) = 1, f (3) = 2.

We store the optimal solution of the subproblem in the array products. The i-th element in the array represents the maximum value of the length product of each segment after cutting the rope of length i into several segments, that is, f (i). The
code implementation is as follows:

int maxproductAfterCutting(int length)
{
	if (length < 2)
		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++)
		{
			int product = products[i] * products[i - j];
			if (max < product)
				max = product;

			products[i] = max;
		}
	}
	max = products[length];
	delete[] products;
	return max;
}

2. Greedy algorithm

The basic idea of ​​the greedy algorithm is. When we use the greedy algorithm to solve the problem, every step can make a greedy choice. Based on this choice, we determine that we can get the optimal solution.

When n> = 5, we cut as much as possible rope of length 3. When the remaining rope length is 4, cut the rope into two lengths of rope.

int maxproductAfterCutting1(int length)
{
	if (length < 2)
		return 0;
	if (length == 2)
		return 1;
	if (length == 3)
		return 2;

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

	//当绳子最后剩下的长度为4的时候,不能再剪去长度为3的绳子段
	//此时更好的方法就是把绳子剪成长度为2的两段
	if (length - timeOf3 * 3 == 1)
		timeOf3 -= 1;

	int timeOf2 = (length - timeOf3 * 3) / 2;
	return (int)(pow(3, timeOf3)) * (int)(pow(2, timeOf2));
}

So why choose this kind of thinking?
When n> = 5, we can prove that 2 (n-2)> n and 3 (n-3)> n, that is, when the length of the remaining rope is greater than or equal to 5, we will cut him Into 3 or 2 lengths of rope.
When n> 5, 3 (n-3)> = 2 (n-2), so we should cut as many lengths of rope as possible.

Published 98 original articles · won praise 9 · views 3653

Guess you like

Origin blog.csdn.net/qq_43412060/article/details/105357429