这题目自己写一直WA,后来发现正确搜索枚举的刻度并不一定是题目中给你的,而可能是两个刻度中间隔的,枚举完整之后答案就会完备而且可能会更优。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=50+5;
int vis[maxn],d[maxn],id[1000000+10],a[maxn];
int n,ans;
bool dfs(int cur)
{
if(cur==ans)
{
for(int i=1;i<=n-1;i++)
if(!vis[i]) return false;
return true;
}
for(int i=1;i<cur;i++)
{
for(int j=1;j<=n-1;j++)
{
if(!vis[j])
{
int dd=a[i]+d[j];
if(dd<=a[cur-1]) continue;
if(dd>=d[n]) continue;
a[cur]=dd;
queue<int> q;
for(int k=1;k<cur;k++)
{
dd=a[cur]-a[k];
if(id[dd]&&!vis[id[dd]])
{
vis[id[dd]]=1;
q.push(id[dd]);
}
}
dd=d[n]-a[cur];
if(id[dd]&&!vis[dd])
{
vis[id[dd]]=1;
q.push(id[dd]);
}
if(dfs(cur+1)) return 1;
while(!q.empty())
{
vis[q.front()]=0;
q.pop();
}
}
}
}
return false;
}
int main()
{
int kase=0;
while(scanf("%d",&n)&&n)
{
for(int i=1;i<=n;i++) {scanf("%d",&d[i]);}
memset(vis,0,sizeof(vis));
sort(d+1,d+n+1);
n=(int)(unique(d+1,d+n+1)-d)-1;
memset(id,0,sizeof(id));
for(int i=1;i<=n;i++) id[d[i]]=i;
ans=2;a[1]=0;
while(ans*(ans-1)/2<n) ans++;
while(!dfs(2)) ans++;
a[ans]=d[n];
printf("Case %d:\n",++kase);
printf("%d\n",ans);
for(int i=1;i<=ans;i++) printf("%s%d",(i==1)?"":" ",a[i]);printf("\n");
}
return 0;
}