HDU 3335 Divisibility (DLX)
Appoint description:
Description
As we know,the fzu AekdyCoin is famous of math,especially in the field of number theory.So,many people call him "the descendant of Chen Jingrun",which brings him a good reputation.
AekdyCoin also plays an important role in the ACM_DIY group,many people always ask him questions about number theory.One day,all members urged him to conduct a lesson in the group.The rookie daizhenyang is extremely weak at math,so he is delighted.
However,when AekdyCoin tells us "As we know, some numbers have interesting property. For example, any even number has the property that could be divided by 2.",daizhenyang got confused,for he don't have the concept of divisibility.He asks other people for help,first,he randomizely writes some positive integer numbers,then you have to pick some numbers from the group,the only constraint is that if you choose number a,you can't choose a number divides a or a number divided by a.(to illustrate the concept of divisibility),and you have to choose as many numbers as you can.
Poor daizhenyang does well in neither math nor programming.The responsibility comes to you!
AekdyCoin also plays an important role in the ACM_DIY group,many people always ask him questions about number theory.One day,all members urged him to conduct a lesson in the group.The rookie daizhenyang is extremely weak at math,so he is delighted.
However,when AekdyCoin tells us "As we know, some numbers have interesting property. For example, any even number has the property that could be divided by 2.",daizhenyang got confused,for he don't have the concept of divisibility.He asks other people for help,first,he randomizely writes some positive integer numbers,then you have to pick some numbers from the group,the only constraint is that if you choose number a,you can't choose a number divides a or a number divided by a.(to illustrate the concept of divisibility),and you have to choose as many numbers as you can.
Poor daizhenyang does well in neither math nor programming.The responsibility comes to you!
Input
An integer t,indicating the number of testcases,
For every case, first a number n indicating daizhenyang has writen n numbers(n<=1000),then n numbers,all in the range of (1...2^63-1).
For every case, first a number n indicating daizhenyang has writen n numbers(n<=1000),then n numbers,all in the range of (1...2^63-1).
Output
The most number you can choose.
Sample Input
1
3
1 2 3
Sample Output
2
Hint:
If we choose 2 and 3,one is not divisible by the other,which is the most number you can choose.
错了好久啊,DLX理解还是不够深。移除的时候当前行不要移除,要保持联系这样才能左右移动,还加了个剪枝函数进去,若剩下的列加上已取的列小于答案值那么就不再取了。
1 #include <iostream> 2 #include <string> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int HEAD = 0; 8 const int SIZE = 1005 * 1005; 9 10 int N,ANS; 11 int U[SIZE],D[SIZE],L[SIZE],R[SIZE],C[1005]; 12 13 void ini(void); 14 void dancing(int); 15 void remove(int); 16 void resume(int); 17 int cut(void); 18 void debug(int); 19 int main(void) 20 { 21 int t; 22 long long s[1005]; 23 24 //freopen("txt.txt","r",stdin); 25 scanf("%d",&t); 26 while(t --) 27 { 28 scanf("%d",&N); 29 for(int i = 1;i <= N;i ++) 30 scanf("%lld",&s[i]); 31 32 ini(); 33 int count = N + 1; 34 for(int i = 1;i <= N;i ++) 35 { 36 int first = count; 37 for(int j = 1;j <= N;j ++) 38 if(s[i] % s[j] == 0 || s[j] % s[i] == 0) 39 { 40 U[count] = U[j]; 41 D[count] = j; 42 L[count] = count - 1; 43 R[count] = count + 1; 44 45 D[U[count]] = count; 46 U[j] = count; 47 C[count] = j; 48 49 count ++; 50 } 51 L[first] = count - 1; 52 R[count - 1] = first; 53 } 54 dancing(0); 55 printf("%d\n",ANS); 56 } 57 58 return 0; 59 } 60 61 62 void ini(void) 63 { 64 ANS = 0; 65 R[HEAD] = 1; 66 L[HEAD] = N; 67 for(int i = 1;i <= N;i ++) 68 { 69 L[i] = i - 1; 70 R[i] = i + 1; 71 U[i] = D[i] = C[i] = i; 72 } 73 R[N] = 0; 74 } 75 76 void dancing(int k) 77 { 78 if(k + cut() <= ANS) 79 return ; 80 if(R[HEAD] == HEAD) 81 { 82 ANS = ANS > k ? ANS : k; 83 return ; 84 } 85 86 int c = R[HEAD]; 87 88 for(int i = D[c];i != c;i = D[i]) 89 { 90 remove(i); 91 for(int j = R[i];j != i;j = R[j]) 92 remove(j); 93 dancing(k + 1); 94 for(int j = L[i];j != i;j = L[j]) 95 resume(j); 96 resume(i); 97 } 98 99 return ; 100 } 101 102 void remove(int c) 103 { 104 for(int i = D[c];i != c;i = D[i]) 105 { 106 L[R[i]] = L[i]; 107 R[L[i]] = R[i]; 108 } 109 } 110 111 void resume(int c) 112 { 113 for(int i = U[c];i != c;i = U[i]) 114 { 115 L[R[i]] = i; 116 R[L[i]] = i; 117 } 118 } 119 120 void debug(int count) 121 { 122 for(int i = 0;i <= count;i ++) 123 printf("U[%d]=%d D[%d]=%d L[%d]=%d R[%d]=%d c[%d]=%d\n",i,U[i],i,D[i],i,L[i],i,R[i],i,C[i]); 124 return ; 125 } 126 127 int cut(void) 128 { 129 int sum = 0; 130 for(int i = R[HEAD];i;i = R[i]) 131 sum ++; 132 return sum; 133 }