标签:ESS fir Once iostream lld eve stack size visible
InputAn 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).
OutputThe 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可重复覆盖的模板是为了找到最小值,所以找到最小值的过程中默认了选择某一个之后和他相关连的都不用在选择了。。。
而这样正好就符合了这个题目的要求,构造的话就是n行n列就好,代表这n个数,将与此数有约数关系的数取值为1.当选中一列时,与此列中的数有约数关系的数
都将删去。另外加一点剪枝使代码更高效。
代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 1000000007 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 const int maxn=1010*1010; 22 struct DLX 23 { 24 int left[maxn],right[maxn],up[maxn],down[maxn],col[maxn]; 25 int head[maxn],num[1010]; 26 int ansed,id; 27 void init(int nn) 28 { 29 int n=nn; 30 for(int i=0;i<=n;i++) 31 { 32 left[i]=i-1; 33 right[i]=i+1; 34 up[i]=down[i]=i; 35 col[i]=i; 36 } 37 left[0]=n; 38 right[n]=0; 39 ansed=0; 40 id=n; 41 memset(num,0,sizeof(num)); 42 memset(head,-1,sizeof(head)); 43 } 44 void link(int x,int y) 45 { 46 id++; 47 up[id]=up[y]; 48 down[id]=y; 49 down[up[y]]=id; 50 up[y]=id; 51 num[y]++; 52 col[id]=y; 53 if(head[x]==-1) 54 { 55 head[x]=left[id]=right[id]=id; 56 } 57 else 58 { 59 left[id]=left[head[x]]; 60 right[id]=head[x]; 61 right[left[head[x]]]=id; 62 left[head[x]]=id; 63 } 64 } 65 void remove(int c)//移除列 66 { 67 for(int i=down[c];i!=c;i=down[i]) 68 { 69 left[right[i]]=left[i]; 70 right[left[i]]=right[i]; 71 } 72 } 73 void reback(int c)//恢复列 74 { 75 for(int i=up[c];i!=c;i=up[i]) 76 { 77 left[right[i]]=i; 78 right[left[i]]=i; 79 } 80 } 81 int A()//未剪掉的列 82 { 83 int s=0; 84 for(int i=right[0];i!=0;i=right[i]) 85 { 86 s++; 87 } 88 return s; 89 } 90 void danc(int step) 91 { 92 if(right[0]==0) 93 { 94 if(step>ansed)//解中的最大值 95 { 96 ansed=step; 97 } 98 return ; 99 } 100 if(A()+step<=ansed)//如果剩下的步骤与已走的步骤比当前答案少,则停止循环 101 { 102 return ; 103 } 104 int c=right[0]; 105 for(int i=c;i!=0;i=right[i])//优先处理列中数字少的 106 { 107 if(num[i]<num[c]) 108 { 109 c=i; 110 } 111 } 112 for(int i=down[c];i!=c;i=down[i]) 113 { 114 remove(i); 115 for(int j=right[i];j!=i;j=right[j]) 116 { 117 remove(j); 118 } 119 danc(step+1); 120 for(int j=left[i];j!=i;j=left[j]) 121 { 122 reback(j); 123 } 124 reback(i); 125 } 126 } 127 }dlx; 128 int main() 129 { 130 int t; 131 scanf("%d",&t); 132 while(t--) 133 { 134 ll num[1010]; 135 int n; 136 scanf("%d",&n); 137 dlx.init(n); 138 for(int i=0;i<n;i++) 139 { 140 scanf("%lld",&num[i]); 141 } 142 for(int i=0;i<n;i++) 143 { 144 for(int j=0;j<n;j++) 145 { 146 if(num[i]%num[j]==0||num[j]%num[i]==0) 147 { 148 dlx.link(i+1,j+1); 149 } 150 } 151 } 152 dlx.danc(0); 153 printf("%d\n",dlx.ansed); 154 } 155 }
标签:ESS fir Once iostream lld eve stack size visible
原文地址:https://www.cnblogs.com/mzchuan/p/11440371.html