题意是说给你一列数,让你从中选出最多的数能够使得其两两之间不能整除
二分图匹配,求最小路径覆盖即可
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1001;
long long n,a[maxn],match[maxn];
bool map[maxn][maxn],vis[maxn];
bool find(int u)
{
for(int i=0;i<n;i++)
{
if(!map[u][i]||vis[i])
continue;
vis[i]=1;
if(match[i]==-1||find(i))
{
match[i]=u;
return 1;
}
}
return 0;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%I64d",&a[i]);
for(int j=0;j<i;j++)
if(a[i]%a[j]==0||a[j]%a[i]==0)
map[j][i]=1;
}
int ans=0;
for(int i=0;i<n;i++)
{
memset(vis,0,sizeof(vis));
if(find(i))
ans++;
}
printf("%d\n",n-ans);
}
return 0;
}
网上居然看到有人用DFS飘过,自己写了下~
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1001;
long long a[maxn],n;
bool vis[maxn];
void DFS(int index)
{
vis[index]=1;
for(int i=index+1;i<n;i++)
if(a[i]%a[index]==0)
{
DFS(i);
return;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
memset(vis,0,sizeof(vis));
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%I64d",&a[i]);
sort(a,a+n);
int ans=0;
for(int i=0;i<n;i++)
if(!vis[i])
{
DFS(i);
ans++;
}
printf("%d\n",ans);
}
return 0;
}