Розбір
Let be the minimum number of moves required to cut a rectangle of size into squares. We'll store this value in the cell .
If the rectangle is already a square , no cuts are needed, so .
A rectangle can be cut either vertically or horizontally. Let's first consider a vertical cut.
With a vertical cut, the rectangle is divided into two rectangles: and . For the resulting rectangles to be non-degenerate, the condition must hold. Then recursively solve the problem for each of these two rectangles and add to the result, as we made one vertical cut. We choose such a that minimizes the sum :
For a horizontal cut, we get a similar formula:
It remains to choose the minimum value among these two options.
Example
In the first test, cuts are required:
The first cut divides the rectangle into and ;
The second cut divides the rectangle into and ;
The third cut divides the rectangle into and ;
Algorithm implementation
Let’s declare constants and the array.
#define MAX 501 #define INF 0x3F3F3F3F int dp[MAX][MAX];
The function returns the minimum number of moves required to cut a rectangle of size into squares.
int f(int a, int b) {
If the rectangle is already a square , no cuts are needed.
if (a == b) return 0;
If the value of is not computed , compute it.
if (dp[a][b] == INF) {
Perform all possible vertical cuts.
for (int k = 1; k < b; k++) dp[a][b] = min(dp[a][b], f(a, k) + f(a, b - k) + 1);
Perform all possible horizontal cuts.
for (int k = 1; k < a; k++) dp[a][b] = min(dp[a][b], f(k, b) + f(a - k, b) + 1); }
Return the result .
return dp[a][b]; }
The main part of the program. Read the dimensions of the rectangle and .
scanf("%d %d", &a, &b);
Compute and print the answer.
memset(dp, 0x3F, sizeof(dp)); printf("%d\n", f(a, b));