给出 n n n个数,将它们分组
使得每组里任意两个数互质
问最少分成多少组和在满足分成最少组的情况下元素最多的组元素最少是多少
考虑暴力
先预处理出 n n n个数两两之间的互质情况
然后二分答案
对于每个答案暴力判断
#include
#include
#define inf 1073741823
int n,i,j,l,r,mid,ans,ans1,ans2;
int a[20],t[20],c[20][20],s[20][20];
int min(int x,int y)
{
if (x<y) return x;
return y;
}
int max(int x,int y)
{
if (x>y) return x;
return y;
}
bool judge(int x,int y)
{
int i;
for (i=2;i<=x&&i<=y;i++)
if (x%i==0&&y%i==0) return true;
return false;
}
void dg(int x,int sum,int mx,int k)
{
int i,j;
bool bj;
if (sum>k) return;
if (mx>=ans) return;
if (x>n)
{
ans=min(ans,mx);
return;
}
for (i=1;i<=sum;i++)
{
bj=true;
for (j=1;j<=t[i];j++)
{
if (c[x][s[i][j]]==true)
{
bj=false;
break;
}
}
if (bj==true)
{
t[i]++;
s[i][t[i]]=x;
dg(x+1,sum,max(mx,t[i]),k);
t[i]--;
}
}
t[sum+1]=1;
s[sum+1][1]=x;
dg(x+1,sum+1,max(mx,1),k);
t[sum+1]=0;
}
int main()
{
freopen("prime.in","r",stdin);
freopen("prime.out","w",stdout);
scanf("%d",&n);
for (i=1;i<=n;i++)
scanf("%d",&a[i]);
for (i=1;i<=n;i++)
for (j=i+1;j<=n;j++)
{
if (judge(a[i],a[j])==true)
{
c[i][j]=true;
c[j][i]=true;
}
}
l=1;
r=n;
while (l<=r)
{
mid=(l+r)>>1;
ans=inf;
dg(1,0,0,mid);
if (ans==inf) l=mid+1;
else
{
ans1=mid;
ans2=ans;
r=mid-1;
}
}
printf("%d %d\n",ans1,ans2);
fclose(stdin);
fclose(stdout);
return 0;
}