hdu3335

现在越来越觉得,dfs和dlx本质上就是一个东西,这题dlx的思路我还是从爆搜引导出来的:

n行n列,对于第i行,如果i % j == 0 || j % i == 0 那么M[i][j] = 1

 

这个题的话,因为是求最大值,所以估价函数也对应有一些变化

#include 
using namespace std;
 
const int MaxN = 1010;
const int MaxM = 1010;
const int MaxNode = MaxN * MaxM;
 
struct DLX{
    int L[MaxNode], R[MaxNode], U[MaxNode], D[MaxNode], col[MaxNode];
    int H[MaxN], S[MaxM];
    int ansnum;
    int n, m, size;
 
    void init(int _n, int _m){
        n = _n;
        m = _m;
        for(int i = 0; i <= m; i ++){
            U[i] = D[i] = i;
            L[i] = i - 1;
            R[i] = i + 1;
            S[i] = 0;
        }
        L[0] = m;
        R[m] = 0;
        size = m;
        ansnum = 0;
        for(int i = 0; i <= n; i ++)
            H[i] = -1;
    }
 
    void Link(int r, int c){
        col[++ size] = c;
        ++ S[c];
        U[size] = U[c];
        D[size] = c;
        D[U[c]] = size;
        U[c] = size;
 
        if(H[r] == -1)
            H[r] = L[size] = R[size] = size;
        else{
            L[size] = L[H[r]];
            R[size] = H[r];
            R[L[H[r]]] = size;
            L[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;
    }
 
    int f(){
        int ret = 0;
        for(int i = R[0]; i != 0; i = R[i])
            ret ++;
        return ret;
    }
 
    void Dance(int d){
    	if(f() + d <= ansnum)
            return;
        if(R[0] == 0){
            if(d > ansnum)
                ansnum = 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;
 
long long num[1010];
 
int main(){
    int T;
    scanf("%d", &T);
    while(T --){
    	int n;
        scanf("%d", &n);
        for(int i = 1; i <= n; i ++)
            scanf("%lld", &num[i]);
        dlx. init(n,n);
 
	    for(int i = 1; i <= n; i ++)
	        for(int j = 1; j <= n; j ++)
	            if(num[i] % num[j] == 0 || num[j] % num[i] == 0)
	                dlx. Link(i, j);
	    dlx. Dance(0);
	    printf("%d\n", dlx. ansnum);
    }
    return 0;
}

 

你可能感兴趣的:(hdu3335)