给出大矩形的长宽, 矩形里面有1,0两个值, 给出小矩形的长宽, 求用最少的小矩形覆盖所有的1.
重复覆盖的模板题。
1 #include <iostream> 2 #include <vector> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <cmath> 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <queue> 11 using namespace std; 12 #define pb(x) push_back(x) 13 #define ll long long 14 #define mk(x, y) make_pair(x, y) 15 #define lson l, m, rt<<1 16 #define mem(a) memset(a, 0, sizeof(a)) 17 #define rson m+1, r, rt<<1|1 18 #define mem1(a) memset(a, -1, sizeof(a)) 19 #define mem2(a) memset(a, 0x3f, sizeof(a)) 20 #define rep(i, a, n) for(int i = a; i<n; i++) 21 #define ull unsigned long long 22 typedef pair<int, int> pll; 23 const double PI = acos(-1.0); 24 const double eps = 1e-8; 25 const int mod = 1e9+7; 26 const int inf = 1061109567; 27 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 28 const int maxn = 305; 29 const int maxNode = 5000; 30 struct DLX { 31 int L[maxNode], R[maxNode], U[maxNode], D[maxNode], row[maxNode], col[maxNode]; 32 int S[maxn], H[maxn], deep, ans[maxn], sz, n, m, k, n1, m1; 33 int g[20][20]; 34 void remove(int c) { 35 for(int i = D[c]; i!=c; i = D[i]) { 36 L[R[i]] = L[i]; 37 R[L[i]] = R[i]; 38 } 39 } 40 void resume(int c) { 41 for(int i = U[c]; i!=c; i = U[i]) { 42 L[R[i]] = i; 43 R[L[i]] = i; 44 } 45 } 46 int h() { 47 int cnt = 0; 48 int vis[250]; 49 mem(vis); 50 for(int i = R[0]; i!=0; i = R[i]) { 51 if(!vis[i]) { 52 cnt++; 53 vis[i] = 1; 54 for(int j = D[i]; j!=i; j = D[j]) { 55 for(int k = R[j]; k!=j; k = R[k]) { 56 vis[col[k]] = 1; 57 } 58 } 59 } 60 } 61 return cnt; 62 } 63 void dfs(int d) { 64 if(d+h()>=deep) 65 return ; 66 if(R[0] == 0) { 67 deep = min(deep, d); 68 return ; 69 } 70 int c = R[0]; 71 for(int i = R[0]; i!=0; i = R[i]) 72 if(S[c]>S[i]) 73 c = i; 74 for(int i = D[c]; i!=c; i = D[i]) { 75 remove(i); 76 for(int j = R[i]; j!=i; j = R[j]) 77 remove(j); 78 dfs(d+1); 79 for(int j = L[i]; j!=i; j = L[j]) 80 resume(j); 81 resume(i); 82 } 83 return ; 84 } 85 void add(int r, int c) { 86 sz++; 87 row[sz] = r; 88 col[sz] = c; 89 S[c]++; 90 U[sz] = U[c]; 91 D[sz] = c; 92 D[U[c]] = sz; 93 U[c] = sz; 94 if(~H[r]) { 95 R[sz] = H[r]; 96 L[sz] = L[H[r]]; 97 L[R[sz]] = sz; 98 R[L[sz]] = sz; 99 } else { 100 H[r] = L[sz] = R[sz] = sz; 101 } 102 } 103 void init(){ 104 mem1(H); 105 for(int i = 0; i<=n; i++) { 106 R[i] = i+1; 107 L[i] = i-1; 108 U[i] = i; 109 D[i] = i; 110 } 111 deep = inf; 112 mem(S); 113 R[n] = 0; 114 L[0] = n; 115 sz = n; 116 } 117 void solve() { 118 mem(g); 119 int cnt = 0, x; 120 for(int i = 0; i<n; i++) { 121 for(int j = 0; j<m; j++) { 122 scanf("%d", &x); 123 if(x) 124 g[i][j] = ++cnt; 125 else 126 g[i][j] = 0; 127 } 128 } 129 scanf("%d%d", &n1, &m1); 130 int r = 0, tmp = n; 131 n = cnt; 132 init(); 133 for(int i = 0; i<tmp-n1+1; i++) { 134 for(int j = 0; j<m-m1+1; j++) { 135 r++; 136 for(int k1 = i; k1<min(i+n1, tmp); k1++) { 137 for(int k2 = j; k2<min(j+m1, m); k2++) { 138 if(g[k1][k2]) { 139 add(r, g[k1][k2]); 140 } 141 } 142 } 143 } 144 } 145 dfs(0); 146 printf("%d ", deep); 147 } 148 }dlx; 149 int main() 150 { 151 while(scanf("%d%d", &dlx.n, &dlx.m)!=EOF) { 152 dlx.solve(); 153 } 154 return 0; 155 }