题解:
列举每一种3的倍数的组合,开始先求出3条边的可行解,则
六条边的可行解可以由两个三条边得来。
代码:
#include<bits/stdc++.h>
using namespace std;
int a[22],n,cnt,ant,is[500007],dp[1050007];
struct node
{
int num,id;
}angle[500007];
bool cmp(const node& a,const node& b)
{
return a.num<b.num;
}
int abs1(int x)
{
if(x<0)return -x;
return x;
}
void init()
{
for(int i=0;i<(1<<n);i++)
{
int ans=0,t=i;
while(t)
{
if(t&1)ans++;
t=t>>1;
}
if(ans%3==0)
{
angle[cnt].id=i;
angle[cnt++].num=ans/3;
}
if(ans==3)
{
int v[4],ans1=0,ans2=0,t=i;
while(t)
{
if(t&1)v[ans1++]=a[ans2];
t=t>>1;
ans2++;
}
if(abs1(v[1]-v[2])<v[0]&&abs1(v[1]-v[0])<v[2]&&abs1(v[2]-v[0])<v[1])
{
is[ant++]=i;
dp[i]=1;
}
}
}
}
int main()
{
int T,cas=0;scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
cnt=0,ant=0;
memset(dp,0,sizeof(dp));
dp[0]=1;
init();
sort(angle,angle+cnt,cmp);
for(int i=0;i<cnt;i++)
{
node e=angle[i];
for(int j=0;j<ant;j++)
{
if(dp[e.id]&&!(e.id&is[j]))//若e.id已存在并且
//.e.id中的边与is[j]中没有重边则dp[e.id|is[j]]=1
dp[e.id|is[j]]=1;
}
}
for(int i=cnt-1;i>=0;i--)
{
if(dp[angle[i].id])
{
printf("Case #%d: %d\n",++cas,angle[i].num);
break;
}
}
}
return 0;
}