zoukankan      html  css  js  c++  java
  • 精确覆盖问题 DLX算法 Hihocoder1317,1321

    两道入门题
    HihoCoder1317
    精确覆盖问题:在一个0-1矩阵中,选定部分行,使得每一列都有且只有一个1。求解一种选法。
    当然使用搜索来解决,先选择一行,然后将不能选的行给删掉,然后再继续向下,完成后恢复现场。(X算法)
    但是这样的方法,在对于矩阵的删除行列和恢复操作太复杂,所以使用一种数据结构--舞蹈链(Dance Link),也就是一个循环十字链表,可以快速的删掉和恢复某行某列。
    结合了舞蹈链的搜索就称作DLX算法。
    题目链接中有了很不错的分析。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int maxn = 200;
    const int maxr = 200;
    const int maxnode = 1e6;
    struct DLX
    {
    	int U[maxnode], D[maxnode], L[maxnode], R[maxnode];
    	int row[maxnode], col[maxnode];
    	int S[maxn], H[maxr], ans[maxr], ansd, sz;
    	int n,m;
    
    	void init(int n, int m){
    		this->n = n; this->m = m;
    		for(int i = 0; i <= m; i++){
    			L[i] = i-1; R[i] = i+1; U[i] = D[i] = i;
    		}
    		L[0] = m; R[m] = 0; sz = m+1;
    		memset(S, 0, sizeof(S));
    		memset(H, -1, sizeof(H));
    	}
    
    	void addNode(int r, int c){
    		row[sz] = r; col[sz] = c;
    		U[sz] = U[c];  D[sz] = c;
    		D[U[sz]] = sz; U[D[sz]] = sz;
    		if(H[r] == -1){
    			L[sz] = sz; R[sz] = sz;
    			H[r] = sz;
    		}else{
    			R[sz] = H[r]; L[sz] = L[H[r]];
    			L[R[sz]] = sz; R[L[sz]] = sz;
    		}
    		S[col[sz]]++; sz++;
    	}
    	#define FOR(i, A, s) for(int i = A[s]; i != s; i = A[i])
    	void remove(int c){
    		R[L[c]] = R[c]; L[R[c]] = L[c];
    		FOR(i, D, c) FOR(j, R, i){
    			U[D[j]] = U[j]; D[U[j]] = D[j]; S[col[j]]--;
    		}
    	}
    	void restore(int c){
    		FOR(i, U, c) FOR(j, L, i){
    			U[D[j]] = j; D[U[j]] = j; S[col[j]]++;
    		}
    		R[L[c]] = c; L[R[c]] = c;
    	}
    	bool dfs(int d){
    		if(R[0] == 0){
    			ansd = d;
    			return true;
    		}
    		int c = R[0];
    		FOR(i, R, 0){
    			if(S[i] < S[c]) c = i;
    		}
    		remove(c);
    		FOR(i, D, c){
    			ans[d] = row[i];
    			FOR(j, R, i) remove(col[j]);
    			if(dfs(d+1)) return true;
    			FOR(j, L, i) restore(col[j]);
    		}
    		restore(c);
    		return false;
    	}
    }dlx;
    int t,n,m;
    int main()
    {
    	cin >> t;
    	while(t--){
    		cin >> n >> m;
    		dlx.init(n,m);
    		for(int i = 1; i <= n; i++){
    			for(int j = 1; j <= m; j++){
    				int tmp;
    				cin >> tmp;
    				if(tmp) dlx.addNode(i,j);
    			}
    		}
    		if(dlx.dfs(0)){
    			cout << "Yes
    ";
    		}else{
    			cout << "No
    ";
    		}
    	}
    	return 0;
    }
    

    HihoCoder1321
    解数独问题:
    可以转变成精确覆盖问题来解决。
    每一行代表这一项决策,共有9*9*9行,i*9*9+j*9+k表示第i行j列的格子里面填k这项决策
    每一列表示一个任务,共有4*9*9
    有四类任务:

    • SLOT(i,j) 第i行j列要放当前的决策值
    • ROW(i,k) 第i行要有k值
    • COL(j,k) 第j列要有k值
    • SUB(s,k) 第s个九宫要有k值
    #include <cstdio>
    #include <cstring>
    #include <vector>
    #include <iostream>
    #include <cstdlib>
    #include <algorithm>
    using namespace std;
    const int maxn = 1020;
    const int maxr = 1020;
    const int maxnode = 2e6;
    struct DLX
    {
    	int U[maxnode], D[maxnode], L[maxnode], R[maxnode];
    	int row[maxnode], col[maxnode];
    	int S[maxn], H[maxr], ans[maxr], ansd, sz;
    	int n,m;
    
    	void init(int n, int m){
    		this->n = n; this->m = m;
    		for(int i = 0; i <= m; i++){
    			L[i] = i-1; R[i] = i+1; U[i] = D[i] = i;
    		}
    		L[0] = m; R[m] = 0; sz = m+1;
    		memset(S, 0, sizeof(S));
    		memset(H, -1, sizeof(H));
    	}
    
    	void addNode(int r, int c){
    		row[sz] = r; col[sz] = c;
    		U[sz] = U[c];  D[sz] = c;
    		D[U[sz]] = sz; U[D[sz]] = sz;
    		if(H[r] == -1){
    			L[sz] = sz; R[sz] = sz;
    			H[r] = sz;
    		}else{
    			R[sz] = H[r]; L[sz] = L[H[r]];
    			L[R[sz]] = sz; R[L[sz]] = sz;
    		}
    		S[col[sz]]++; sz++;
    	}
    	#define FOR(i, A, s) for(int i = A[s]; i != s; i = A[i])
    	void remove(int c){
    		R[L[c]] = R[c]; L[R[c]] = L[c];
    		FOR(i, D, c) FOR(j, R, i){
    			U[D[j]] = U[j]; D[U[j]] = D[j]; S[col[j]]--;
    		}
    	}
    	void restore(int c){
    		FOR(i, U, c) FOR(j, L, i){
    			U[D[j]] = j; D[U[j]] = j; S[col[j]]++;
    		}
    		R[L[c]] = c; L[R[c]] = c;
    	}
    	bool dfs(int d){
    		if(R[0] == 0){
    			ansd = d;
    			return true;
    		}
    		int c = R[0];
    		FOR(i, R, 0){
    			if(S[i] < S[c]) c = i;
    		}
    		remove(c);
    		FOR(i, D, c){
    			ans[d] = row[i];
    			FOR(j, R, i) remove(col[j]);
    			if(dfs(d+1)) return true;
    			FOR(j, L, i) restore(col[j]);
    		}
    		restore(c);
    		return false;
    	}
    	bool solve(vector<int> &v){
    		v.clear();
    		if(!dfs(0)) return false;
    		for(int i = 0; i < ansd; i++){
    			v.push_back(ans[i]);
    		}
    		return true;
    	}
    }dlx;
    int t,n,m;
    int cnt_r, cnt_c;
    int mp[10][10];
    int encode(int x, int y, int z){
    	return x*81+y*9+z+1;
    }
    void decode(int code, int &x, int &y, int &z){
        code--;
    	z = code%9; code /= 9;
    	y = code%9; code /= 9;
    	x = code%9;
    }
    const int SLOT = 0;
    const int ROW = 1;
    const int COL = 2;
    const int SUB = 3;
    int main()
    {
    	cin >> t;
    	cnt_r = 9*9*9; cnt_c = 9*9*4;
    	while(t--){
    		dlx.init(cnt_r, cnt_c);
    		for(int i = 0; i < 9; i++){
    			for(int j = 0; j < 9; j++){
    				cin >> mp[i][j];
    			}
    		}
    		for(int i = 0; i < 9; i++){
    			for(int j = 0; j < 9; j++){
    				for(int k = 0; k < 9; k++){
    					if(mp[i][j] == 0 || mp[i][j] == k+1){
    						int r = encode(i, j, k);
    						dlx.addNode(r, encode(SLOT, i, j));
    						dlx.addNode(r, encode(ROW, i, k));
    						dlx.addNode(r, encode(COL, j, k));
    						dlx.addNode(r, encode(SUB, (i/3)*3+j/3, k));// 6,9
    					}
    				}
    			}
    		}
    		vector<int> v;
    		dlx.solve(v);
    		for(int i = 0; i < v.size(); i++){
    			int r, c, k;
    			decode(v[i], r, c, k);
    			mp[r][c] = k+1;
    		}
    		for(int i = 0; i < 9; i++){
    			for(int j = 0; j < 9; j++){
    				if(j) cout << ' ';
    				cout << mp[i][j];
    			}
    			cout << "
    ";
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    ABAP-Spotlight on ABAP for SAP HANA – Again
    ABAP-ABAP Development
    ABAP-Performance Guidelines for ABAP Development on the SAP HANA Database
    ABAP-Getting Started with ABAP Core Data Services (CDS)
    ABAP-Technology and Runtime Environment
    ABAP-Test and Analysis Tools
    ABAP-Connectivity Wiki
    python爬虫
    python爬虫
    python爬虫
  • 原文地址:https://www.cnblogs.com/Alruddy/p/7707631.html
Copyright © 2011-2022 走看看