Pirme——世紀大暴力
阿新 • • 發佈:2020-08-03
description
給定n個正整數,將其分為若干組,使得每組中的數兩兩互質.求出最小分組數及分組最小的情況下,使元素個數最多的組元素個數最小的最大組的元素個數.
solution
又是一場世紀大暴力.只需暴力dfs尋找分組,然後暴力統計答案,注意最優性剪枝即可.
code
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<queue> #include<map> #define R register #define next kdjadskfj #define debug puts("mlg") #define mod 10007 #define Mod(x) ((x%mod+mod)%mod) using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; inline ll read(); inline void write(ll x); inline void writeln(ll x); inline void writesp(ll x); ll ans,res; ll n; ll num[100001]; ll a[20][20],h[20],cnt; bool check[20][20]; inline void dfs(ll x){ if(cnt>ans) return; if(x==n+1){ if(cnt<ans){ ans=cnt; res=0; for(R ll i=1;i<=cnt;i++) res=max(res,h[i]); } else{ ll rem=0; for(R ll i=1;i<=cnt;i++) rem=max(rem,h[i]); if(rem<res) res=rem; } return; } for(R ll i=1;i<=cnt;i++){ bool flag=true; for(R ll j=1;j<=h[i];j++){ if(!check[a[i][j]][x]) flag=false; } if(flag){ a[i][++h[i]]=x; dfs(x+1); --h[i]; } } a[++cnt][h[cnt]=1]=x; dfs(x+1); --h[cnt];--cnt; } int main(){ freopen("prime.in","r",stdin); freopen("prime.out","w",stdout); n=read(); ans=((ull)1<<63)-1; for(R ll i=1;i<=n;i++) num[i]=read(); for(R ll i=1;i<=n;i++){ for(R ll j=i+1;j<=n;j++){ if(__gcd(num[i],num[j])==1) check[i][j]=check[j][i]=true; } } dfs(1); writesp(ans);writeln(res); } inline ll read(){ll x=0,t=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*t;} inline void write(ll x){if(x<0){putchar('-');x=-x;}if(x<=9){putchar(x+'0');return;}write(x/10);putchar(x%10+'0');} inline void writesp(ll x){write(x);putchar(' ');} inline void writeln(ll x){write(x);putchar('\n');}