可以将需要丈量的状态进行hash,然后进行bfs,这里状态的设计和枚举需要注意。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=60;
struct node
{
int sz;
int st;
int r[10];
};
int n;
int d[maxn],g[1<<20];
int vis[1<<22];
int ifsame(int x,node t)
{
for(int i=0;i<t.sz;i++)
if(t.r[i]==x) return 1;
return 0;
}
void conduct(node& t,int x)
{
for(int i=0;i<t.sz;i++)
{
int tmp=abs(t.r[i]-x);
if(g[tmp]!=-1) t.st|=(1<<g[tmp]);
}
t.r[t.sz++]=x;
sort(t.r,t.r+t.sz);
}
node bfs()
{
queue<node> q;
memset(vis,0,sizeof(vis));
node tmp;
tmp.sz=1;
tmp.st=0;
tmp.r[0]=0;
q.push(tmp);
vis[0]=1;
while(!q.empty())
{
node u=q.front();q.pop();
for(int i=0;i<u.sz;i++)
{
for(int j=0;j<n;j++)
{
if(u.st&(1<<j)) continue;
int x=u.r[i]+d[j];
if(ifsame(x,u) || x>d[n-1]) continue;
node v=u;
conduct(v,x);
if(!vis[v.st])
{
vis[v.st]=1;
if(v.st==(1<<n)-1) return v;
q.push(v);
}
}
for(int j=0;j<n;j++)
{
if(u.st&(1<<j)) continue;
int x=u.r[i]-d[j];
if(ifsame(x,u) || x>d[n-1] || x<0) continue;
node v=u;
conduct(v,x);
if(!vis[v.st])
{
vis[v.st]=1;
if(v.st==(1<<n)-1) return v;
q.push(v);
}
}
}
}
return tmp;
}
int main()
{
//freopen("in.txt","r",stdin);
int kase=1;
while(scanf("%d",&n)!=EOF && n)
{
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++) scanf("%d",&d[i]);
sort(d,d+n);
n=unique(d,d+n)-d;
memset(g,-1,sizeof(g));
for(int i=0;i<n;i++) g[d[i]]=i;
node ans=bfs();
printf("Case %d:\n",kase++);
printf("%d\n",ans.sz);
for(int i=0;i<ans.sz;i++)
{
if(i) printf(" %d",ans.r[i]);
else printf("%d",ans.r[i]);
}
puts("");
}
return 0;
}