#include<stdio.h>
#include<string.h>
#define N 1100
__int64 a[N];
int map[N][N],mark[N],link[N],n;
int find(int k)
{
int i;
for(i=1;i<=n;i++)
{
if(!mark[i]&&map[k][i])
{
mark[i]=1;
if(!link[i]||find(link[i]))
{
link[i]=k;
return 1;
}
}
}
return 0;
}
int main()
{
int t,i,j,sum;
scanf("%d",&t);
while(t--)
{
memset(map,0,sizeof(map));
memset(link,0,sizeof(link));
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%I64d",&a[i]);
for(j=1;j<i;j++)
if(a[i]%a[j]==0||a[j]%a[i]==0)
map[i][j]=1;
}
sum=0;
for(i=1;i<=n;i++)
{
memset(mark,0,sizeof(mark));
sum+=find(i);
}
printf("%d\n",n-sum);
}
return 0;
}
选出n个数,任意两个数之间不能出现整除的情况,把能整除的都建边,
要求的就是任意两个之间没有公共边的,就是最大独立集,用最小路径覆盖同样可以。
贪心做法
#include<stdio.h>
#include<string.h>
#define N 1100
int b[N],map[N][N],mark[N];
__int64 a[N];
int main()
{
int t,i,j,ans,p,min,n;
scanf("%d",&t);
while(t--)
{
memset(map,0,sizeof(map));
memset(b,0,sizeof(b));
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%I64d",&a[i]);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
if(i!=j&&(a[i]%a[j]==0||a[j]%a[i]==0))
{
map[i][j]=1;
b[i]++;
}
}
memset(mark,0,sizeof(mark));
ans=0;
while(1)
{
p=-1;min=100000;
for(i=1;i<=n;i++)
{
if(b[i]<min&&!mark[i])
{
min=b[i];p=i;
}
}
if(p==-1)
break;
mark[p]=1;
ans++;
for(i=1;i<=n;i++)
{
if(map[p][i]==1)
mark[i]=1;
}
}
printf("%d\n",ans);
}
return 0;
}
hdu 3335
最新推荐文章于 2020-01-27 10:07:07 发布