A rectangle of N * m is given. The coordinates are (0, 0 )~ (N, m ). Then we will give you a small P rectangle with the coordinates (x1, Y1 )~ (X2, Y2), you can select the smallest rectangle so that these rectangles can overwrite the entire rectangle without overlap. (N, m <= 30)
Idea: precise coverage of dancing links.
We divide the N * m rectangle into N * m small squares, so we only need to ensure that each small square is overwritten and only once.
The column represents each small square, and the row represents the rectangle you selected. If you select this rectangle to overwrite a small square, the corresponding grid is 1; otherwise, the corresponding grid is 0.
Up to 30*30 = 900 columns, up to 500 rows
# Include <stdio. h> # include <string. h >#include <algorithm> # include <vector> using namespace STD; const int maxn = 900 + 10; const int maxr = 500 + 10; const int maxnode = 500*900 + maxr + 10; # define for (I, A, S) for (INT I = A [s]; I! = S; I = A [I]) struct DLX {// Number of maxn columns, total number of maxnode nodes, number of maxr rows int N, SZ; int s [maxn]; int row [maxnode], Col [maxnode]; int L [maxnode], R [maxnode], U [maxnode], d [maxnode]; int H [maxr]; int anSd, ANS [maxr]; void Init (int n) {n = N; // The virtual node of the first line for (INT I = 0; I <= N; I ++) {u [I] = d [I] = I; L [I] = I-1; R [I] = I + 1 ;} R [N] = 0; L [0] = N; SZ = n + 1; // number of each column memset (S, 0, sizeof (s )); // H [I] =-1 indicates that this row does not have 1 // otherwise, it indicates the number of memset (H,-1, sizeof (H) for the Sz of the first 1 ));} // Add a 1 void Link (int r, int c) {row [SZ] = r; Col [SZ] = C in Column C of row R; s [c] ++; d [SZ] = C; U [SZ] = U [c]; d [U [c] = SZ; U [c] = SZ; If (H [R] <0) {H [R] = L [SZ] = R [SZ] = SZ ;} else {R [SZ] = H [R]; L [SZ] = L [H [R]; R [L [SZ] = SZ; L [R [SZ] = SZ;} SZ ++;} // delete column C void remove (int c) {// Delete the C column in the virtual node l [R [c] = L [c]; R [L [c] = R [c]; // traverse for (I, D, C) down from column c {// Delete the row for (J, R, I) {d [U [J] = d [J]; U [d [J] = U [J]; -- s [col [J] ;}} // restore column C void restore (INT c) {for (I, U, c) {for (J, l, I) {++ s [col [J]; U [d [J] = d [U [J] = J ;}} L [R [c] = R [L [c] = C;} void DFS (INT d) {// trim if (D> = Best) {return ;} // R [0] = 0 indicates finding a feasible solution if (R [0] = 0) {best = D; return ;}// locate the column with the smallest s value, accelerate search speed int c = R [0]; for (I, R, 0) if (s [I] <s [c]) C = I; // delete column C remove (c); // traverse the rows with 1 in the selected column for (I, D, C) {ans [d] = row [I]; // Delete the column for (J, R, I) {remove (COL [J]);} DFS (D + 1) in the selected row ); // reply to the deleted column for (J, l, I) {restore (COL [J]) ;}} restore (c) ;}int solve () {best = inf; DFS (0); If (best = inf) Return-1; elsereturn best;} int best; const static int INF = 0x3f3f3f;} DLX; int main () {int CAS; scanf ("% d", & CAS); While (CAS --) {int n, m, p; scanf ("% d", & N, & M, & P); DLX. init (N * m); For (INT I = 1; I <= P; I ++) {int X1, Y1, X2, Y2; scanf ("% d", & X1, & Y1, & X2, & Y2); For (INT x = x1; x <X2; X ++) {for (INT y = Y1; y <Y2; y ++) {DLX. link (I, x * m + Y + 1) ;}} printf ("% d \ n", DLX. solve ();} return 0 ;}
Zoj 3209 treasure map (precise coverage of dancing links)