1. 程式人生 > 實用技巧 >Pirme——世紀大暴力

Pirme——世紀大暴力

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');}