课重复覆盖的模板
#include <iostream> #include<stdio.h> #include<cmath> #include<string.h> #include<algorithm> #include<string> #include<vector> using namespace std; const int inf = 0x3fffffff; const int maxn = 15*15+10; const int maxnode = maxn*maxn; struct DLX { int n,m,sz; int U[maxnode],D[maxnode],R[maxnode],L[maxnode],row[maxnode],col[maxnode]; int H[maxn],S[maxn]; int ans; void init(int n,int m) { this->n=n; this->m=m; for(int i = 0; i <= m; i++) { S[i] = 0; U[i] = D[i] = i; L[i] = i-1; R[i] = i+1; } R[m] = 0; L[0] = m; sz = m; for(int i = 1; i <= n; i++)H[i] = -1; } void Link(int r,int c) { ++S[col[++sz]=c]; row[sz] = r; U[sz] = U[c]; D[U[c]] = sz; D[sz] = c; U[c] = sz; if(H[r] < 0)H[r] = L[sz] = R[sz] = sz; else { L[sz] = L[H[r]]; R[L[H[r]]] = sz; R[sz] = H[r]; L[H[r]] = sz; } } #define FOR(i,A,s) for(int i=A[s];i!=s;i=A[i]) void remove(int c) { // L[R[c]]=L[c]; // R[L[c]]=R[c]; FOR(i,D,c) { L[R[i]]=L[i]; R[L[i]]=R[i]; } } void restore(int c) { FOR(i,U,c) { L[R[i]]=i; R[L[i]]=i; } // L[R[c]]=c; // R[L[c]]=c; } bool v[maxn]; int f() { int ret = 0; for(int c = R[0]; c != 0; c = R[c]) v[c] = true; for(int c = R[0]; c != 0; c = R[c]) if(v[c]) { ret++; v[c] = false; for(int i = D[c]; i != c; i = D[i]) for(int j = R[i]; j != i; j = R[j]) v[col[j]] = false; } return ret; } void dfs(int d) { if(d+f()>=ans) return ; if(R[0]==0) { ans=min(ans,d); //找到了解 return ; } //找到S最小的列c int c=R[0]; //第一个为删除的列 FOR(i,R,0) if(S[i]<S[c]) c=i; FOR(i,D,c) { remove(i); FOR(j,R,i) remove(j); dfs(d+1); FOR(j,L,i) restore(j); restore(i); } return; } int solve() { ans=inf; dfs(0); return ans; } }; int G[20][20]; int id[20][20]; int main() { int n,m; while(~scanf("%d %d",&n,&m)) { int cnt=0; memset(id,-1,sizeof id); for(int i=0; i<n; i++) { for(int j=0; j<m; j++) { scanf("%d",&G[i][j]); if(G[i][j]) { id[i][j]=++cnt; } } } DLX X; X.init(n*m,cnt); int l,w; scanf("%d %d",&l,&w); int r=1; for(int i=0; i+l<=n; i++) for(int j=0; j+w<=m; j++) { for(int k=0; k<l; k++) for(int e=0; e<w; e++) if(G[i+k][j+e]) X.Link(r,id[i+k][j+e]); r++; } printf("%d\n",X.solve()); } return 0; }