DLX重複覆蓋
阿新 • • 發佈:2018-12-09
const int maxn = 15*15+10; const int maxm = 15*15+10; const int maxnode = maxn*maxm; const int inf = 0x3f3f3f3f; struct DLX { int n,m,sizes,H[maxn],S[maxm],ansd; int U[maxnode],D[maxnode],L[maxnode],R[maxnode],Row[maxnode],Col[maxnode]; void init( int _n , int _m ) { n = _n; 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; sizes = m; for ( int i=1 ; i<=n ; i++ ) H[i] = -1; } void Link( int r , int c ) { ++S[Col[++sizes]=c]; Row[sizes] = r; D[sizes] = D[c]; U[D[c]] = sizes; U[sizes] = c; D[c] = sizes; if ( H[r]<0 ) H[r] = L[sizes] = R[sizes] = sizes; else { R[sizes] = R[H[r]]; L[R[H[r]]] = sizes; L[sizes] = H[r]; R[H[r]] = sizes; } } void Remove( int c ) { for ( int i=D[c] ; i!=c ; i=D[i] ) L[R[i]] = L[i],R[L[i]] = R[i]; } void Resume( int c ) { for ( int i=U[c] ; i!=c ; i=U[i] ) L[R[i]] = R[L[i]] = i; } bool v[maxm]; 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 Dance( int d ) { if ( d+f()>=ansd ) return; if ( R[0]==0 ) { if ( d<ansd ) ansd = d; return; } int c = R[0]; for ( int i=R[0] ; i!=0 ; i=R[i] ) if ( S[i]<S[c] ) c = i; for ( int i=D[c] ; i!=c ; i=D[i] ) { Remove( i ); for ( int j=R[i] ; j!=i ; j=R[j] ) Remove( j ); Dance( d+1 ); for ( int j=L[i] ; j!=i ; j=L[j] ) Resume( j ); Resume( i ); } } }dlx; int a[20][20],id[20][20]; int main() { for ( int n,m ; scanf ( "%d%d" , &n , &m )==2 ; ) { int sz = 0; memset ( id , 0 , sizeof(id) ); for ( int i=0 ; i<n ; i++ ) for ( int j=0 ; j<m ; j++ ) { scanf ( "%d" , &a[i][j] ); if ( a[i][j]==1 ) id[i][j] = ++sz; } dlx.init( n*m , sz ); sz = 1; int n1,m1; scanf ( "%d%d" , &n1 , &m1 ); for ( int i=0 ; i<n ; i++ ) for ( int j=0 ; j<m ; j++ ) { for ( int x=0 ; x<n1&&i+x<n ; x++ ) for ( int y=0 ; y<m1&&j+y<m ; y++ ) if ( id[i+x][j+y] ) dlx.Link( sz , id[i+x][j+y] ); sz++; } dlx.ansd = inf; dlx.Dance(0); printf ( "%d\n" , dlx.ansd ); } return 0; }