现在越来越觉得,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;
}