标签:
给你一系列的长度。你要制作一个有m个刻度的尺子,使得任意一个长度都能以某两个刻度之间的距离表示
要求m尽量小的前提下尺子长度尽量小。你可以认为刻度数不超过7
首先要想明白的一点,尺子长度就为这n个长度中的最大值。以这个值为长度的尺子一定能满足m尽量小。
然后我想水几句,自从长春打了个铜本人就变成了颓狗,不仅什么都没预习,四级也没看,天天都在玩。而就在这时,突然被告知ec有名额了.... 了
然后我们如何去搜索呢?我们的刻度是任意的,但可以跟给定长度建立关系。我们枚举一个当前还不能表示的长度,然后枚举这个长度是由哪个已有刻度和新刻度共同产生的。这样的做法是显然能得到解的。还有一个重要问题,如何判重呢?我们只要判断当前状态能表示哪些刻度就有了——即表示的给定长度都相同的两种状态视为同一种状态。这点还真有点想不明白。等弱想明白了再改
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
using namespace std;
const int maxm=58;
const int maxn=1000008;
int a[maxm];
int b[maxm];
int idx;
set<int> ans;
int shit[maxn];
bool vis[maxn<<5];
struct fuck{
int state;
set<int> ans;
}f;
void bfs()
{
queue<fuck> q;
f.ans.clear();f.ans.insert(0);f.state=0;
q.push(f);
int i;
while(!q.empty())
{
f=q.front();q.pop();
// printf("%d\n",f.state);
if(f.state==(1<<idx)-1)
{
if(ans.size()==0)
ans=f.ans;
else
{
if(ans.size()<f.ans.size()) return;
else if(ans.size()>f.ans.size()) ans=f.ans;
else
{
if(*ans.rbegin()>*f.ans.rbegin())
ans=f.ans;
}
}
}
if(f.ans.size()==7) continue;
for(i=0;i<idx;i++)
{
if(f.state&(1<<i)) continue;
for(set<int>::iterator it =f.ans.begin();
it!=f.ans.end();it++)
{
// printf("%dbitch\n",*it);
if(*it>b[i])
{
fuck p=f;
int sum=*it-b[i];
for(set<int> :: iterator it2=f.ans.begin();
it2!=f.ans.end();it2++)
{
int nu=abs(*it2-sum);
// printf("bitch%d\n",nu);
if(shit[nu]==-1) continue;
p.state=(p.state|(1<<shit[nu]));
}
p.ans.insert(sum);
if(!vis[p.state])
{
q.push(p);
vis[p.state]=true;
}
}
if(*it+b[i]<=b[idx-1])
{
fuck p=f;
int sum=*it+b[i];
for(set<int> :: iterator it2=f.ans.begin();
it2!=f.ans.end();it2++)
{
int nu=abs(*it2-sum);
if(shit[nu]==-1) continue;
p.state=(p.state|(1<<shit[nu]));
}
p.ans.insert(sum);
if(!vis[p.state])
{
q.push(p);
vis[p.state]=true;
}
}
}
}
}
}
int main()
{
int i,j,n,m;
int cas=1;
while(scanf("%d",&n)==1&&n)
{
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
idx=0;
memset(vis,false,sizeof(vis));
memset(shit,-1,sizeof(shit));
ans.clear();
for(i=1;i<=n;i++)
{
if(shit[a[i]]!=-1) continue;
b[idx++]=a[i];
shit[a[i]]=i;
}
for(i=0;i<idx;i++)
shit[b[i]]=i;
// for(i=0;i<idx;i++) printf("%d ",b[i]);printf("\n");
bfs();
set<int> ::iterator it;
bool flag=false;
printf("Case %d:\n",cas++);
printf("%d\n",ans.size());
for(it=ans.begin();it!=ans.end();it++)
{
if(flag) printf(" ");
printf("%d",*it);
flag=true;
}
printf("\n");
}
return 0;
}
标签:
原文地址:http://www.cnblogs.com/bitch1319453/p/5011452.html