First of all, let's get angry, because although k <= 4, K is actually less than or equal to 3.
Of course, I will not comment on some k <= 3 and Ms.
Okay, but how to search? Considering the small number of rectangles, we can search for rectangles.
I will not talk about some god's practices here. I will first talk about a simple and easy-to-write sand tea practice that K = 4 can also be used.
We can open a struct to store a rectangle, such:
struct Point{int x,y;};int cmpx(Point a,Point b){return a.x<b.x;}int cmpy(Point a,Point b){return a.y<b.y;}struct Mrx{Point px[N],py[N];int n;}mrx[10];
Then we can see that I opened 10 MRX and now there is a nature: the numbers of the rectangles in each layer are basically fixed, they are all the rectangles of the previous layer plus the two rectangles added to this layer and then the split rectangle is removed. This can be handled by some pre array magic horse. The rectangles have been split. Then the total number of rectangles does not exceed DEP * 2, and the time complexity of enumeration is very small.
Of course, I certainly did not open this pre array for lazy. I directly passed a parameter using the small PROPERTY OF k <= 3, saying which one was removed from the previous layer, and then quickly ran through the water, this is wrong when K is large. Don't bother reading the code ~~, After all, K is so small.
How can we split it? It is to open two new rectangles, and place the points of the old rectangles into the new two rectangles. The idea of each split is to split the X fields into two, or split the y fields into two.
It's so plain tea. If you don't understand it, read the code.
# Include <cstdio> # include <cstring> # include <algorithm> # define N 55 # define INF 0x3f3f3fusing namespace STD; struct point {int X, Y ;}; int cmpx (point a, point B) {return. x <B. x;} int cmpy (point a, point B) {return. Y <B. y;} struct MRX {point PX [N], Py [N]; int N;} MRX [10]; int n, m, ANS = inf; void DFS (int dep, int from) {int t_ans = 0, I, J, K, to; int sta = max (1, dep-2 <1 ), end = DEP * 2-1; for (I = sta; I <= end; I ++) if (I! = From) t_ans + = (MRX [I]. px [MRX [I]. n]. x-MRX [I]. px [1]. x) * (MRX [I]. PY [MRX [I]. n]. y-MRX [I]. PY [1]. y); ans = min (t_ans, ANS); If (! Ans) return; If (DEP = m) return; for (I = sta; I <= end; I ++) if (I! = From) {for (j = 1; j <MRX [I]. N; j ++) {If (MRX [I]. PX [J]. X! = MRX [I]. px [J + 1]. x)/* Cut x */{to = DEP * 2; MRX [to]. N = J; For (k = 1; k <= MRX [to]. n; k ++) {MRX [to]. px [K]. X = MRX [to]. PY [K]. X = MRX [I]. px [K]. x; MRX [to]. px [K]. y = MRX [to]. PY [K]. y = MRX [I]. px [K]. y;} Sort (MRX [to]. PX + 1, MRX [to]. PX + MRX [to]. n + 1, cmpx); sort (MRX [to]. PY + 1, MRX [to]. PY + MRX [to]. n + 1, cmpy); To = DEP * 2 + 1; MRX [to]. N = MRX [I]. n-J; For (k = 1; k <= MRX [to]. n; k ++) {MRX [to]. px [K]. X = MRX [to]. PY [K]. X = MRX [I]. px [K + J]. x; MRX [to]. px [K]. y = MRX [to]. PY [K]. y = m RX [I]. px [K + J]. y;} Sort (MRX [to]. PX + 1, MRX [to]. PX + MRX [to]. n + 1, cmpx); sort (MRX [to]. PY + 1, MRX [to]. PY + MRX [to]. n + 1, cmpy); DFS (DEP + 1, I);} If (MRX [I]. PY [J]. y! = MRX [I]. PY [J + 1]. y)/* Cut y */{to = DEP * 2; MRX [to]. N = J; For (k = 1; k <= MRX [to]. n; k ++) {MRX [to]. px [K]. X = MRX [to]. PY [K]. X = MRX [I]. PY [K]. x; MRX [to]. px [K]. y = MRX [to]. PY [K]. y = MRX [I]. PY [K]. y;} Sort (MRX [to]. PX + 1, MRX [to]. PX + MRX [to]. n + 1, cmpx); sort (MRX [to]. PY + 1, MRX [to]. PY + MRX [to]. n + 1, cmpy); To = DEP * 2 + 1; MRX [to]. N = MRX [I]. n-J; For (k = 1; k <= MRX [to]. n; k ++) {MRX [to]. px [K]. X = MRX [to]. PY [K]. X = MRX [I]. PY [K + J]. x; MRX [to]. px [K]. y = MRX [to]. PY [K]. y = MRX [I]. PY [K + J]. y;} Sort (MRX [to]. PX + 1, MRX [to]. PX + MRX [to]. n + 1, cmpx); sort (MRX [to]. PY + 1, MRX [to]. PY + MRX [to]. n + 1, cmpy); DFS (DEP + 1, I) ;}}} int main () {// freopen ("test. in "," r ", stdin); int I, j, k; int A, B, C; scanf (" % d ", & N, & M ); MRX [1]. N = N; for (I = 1; I <= N; I ++) {scanf ("% d", & A, & B ); MRX [1]. px [I]. X = MRX [1]. PY [I]. X = A; MRX [1]. px [I]. y = MRX [1]. PY [I]. y = B;} Sort (MRX [1]. PX + 1, MRX [1]. PX + n + 1, cmpx); sort (MRX [1]. PY + 1, MRX [1]. PY + n + 1, cmpy); DFS (1, 0); printf ("% d \ n", ANS); Return 0 ;}
Here I will refer to another special killing technique: DP ?!!! I said I didn't understand it or want to understand it. After all, there is a library on the Internet that seems to have proposed this algorithm first, but he said it seems that it cannot cover all the situations. Maybe it is a cheat component, so I still don't want to read it.
Source: http://www.cnblogs.com/noip/archive/2012/08/13/2635815.html
#include<iostream>#define Max 1000000using namespace std;int n,m,ans=Max,x[52],y[52],f[52][52][5]={0};int High(int i,int j){ int maxh=0,minh=1000,temp=i; while(temp<=j) maxh=max(maxh,y[temp++]); temp=i; while(temp<=j) minh=min(minh,y[temp++]); return maxh-minh; }void Dp(){ for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) for(int k=2;k<=m;++k) f[i][j][k]=Max; for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) f[i][j][1]=(x[j]-x[i])*High(i,j); for(int i=1;i<=n;++i) for(int k=1;k<=m;++k) f[i][i][k]=0; for(int k=2;k<=m;++k) for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) for(int l=i+1;l<=j;++l) f[i][j][k]=min(f[i][j][k],f[i][l-1][k-1]+(x[j]-x[l])*High(l,j)); ans=min(ans,f[1][n][m]); }int main(){ cin>>n>>m; for(int i=1;i<=n;++i) cin>>x[i]>>y[i]; for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(x[i]>x[j]) {swap(x[i],x[j]);swap(y[i],y[j]);} else if(x[i]==x[j]&&y[i]>=y[j]) swap(y[i],y[j]); Dp(); for(int i=1;i<=n;++i) swap(x[i],y[i]); for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(x[i]>x[j]) {swap(x[i],x[j]);swap(y[i],y[j]);} else if(x[i]==x[j]&&y[i]>=y[j]) swap(y[i],y[j]); Dp(); cout<<ans<<endl; return 0; }
Copy the Translation results to Google
[Noip2002] rectangular coverage DFS