• FZU 1686 神龙的难题(DLX反复覆盖)


    FZU 1686 神龙的难题

    题目链接

    题意:中文题

    思路:每个1看成列,每个位置作为左上角的矩阵看成行。dlx反复覆盖就可以

    代码:

    #include <cstdio>
    #include <cstring>
    
    using namespace std;
    
    const int MAXNODE = 66666;
    const int INF = 0x3f3f3f3f;
    const int MAXM = 230;
    const int MAXN = 230;
    int K;
    
    struct DLX {
    
    	int n,m,size;
    
    	int U[MAXNODE], D[MAXNODE], R[MAXNODE], L[MAXNODE], row[MAXNODE], col[MAXNODE];
    	int H[MAXN], S[MAXM];
    	int ansd, ans[MAXN];
    
    	void init(int n,int m) {
    		this->n = n;
    		this->m = m;
    		ansd = INF;
    		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; 
    		size = m;
    		for(int i = 1; i <= n; i++)
    			H[i] = -1;
    	}
    
    	void Link(int r,int c) {
    		++S[col[++size] = c];
    		row[size] = r;
    		D[size] = D[c];
    		U[D[c]] = size;
    		U[size] = c;
    		D[c] = size;
    		if(H[r] < 0) H[r] = L[size] = R[size] = size;
    		else {
    			R[size] = R[H[r]];
    			L[R[H[r]]] = size;
    			L[size] = H[r];
    			R[H[r]] = size;
    		}
    	}
    
    	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[MAXNODE];
    
    	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);
    			ans[d] = row[i];
    			Dance(d + 1);
    			for(int j = L[i]; j != i; j = L[j]) resume(j);
    			resume(i);
    		}
    	}
    } gao;
    
    const int N = 20;
    
    int n, m, g[N][N], n1, m1, to[N][N];
    
    int main() {
    	while (~scanf("%d%d", &n, &m)) {
    		int cnt = 0;
    		for (int i = 0; i < n; i++)
    			for (int j = 0; j < m; j++) {
    				scanf("%d", &g[i][j]);
    				if (g[i][j]) to[i][j] = ++cnt;
    			}
    		scanf("%d%d", &n1, &m1);
    		gao.init(n * m, cnt);
    		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 (g[i + x][j + y]) gao.Link(i * m + j + 1, to[i + x][j + y]);
    					}
    				}
    			}
    		}
    		gao.Dance(0);
    		printf("%d
    ", gao.ansd);
    	}
    	return 0;
    }


  • 相关阅读:
    前端面试题目汇总摘录(HTML 和 CSS篇)
    The Road to learn React书籍学习笔记(第三章)
    The Road to learn React书籍学习笔记(第二章)
    算法复习:动态规划
    算法复习:回溯法
    算法复习:图
    算法复习:二叉树专题
    算法复习:最短路Dijkstra
    算法复习:BFS与DFS
    算法复习:标记数组 / 数组
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5194265.html
Copyright © 2020-2023  润新知