您的位置:首页 > 编程语言 > C语言/C++

【JZOJ 4314】【NOIP2015模拟11.4】老司机

2018-01-30 21:11 417 查看
问题描述



输入



输出



样例输入

4

1 3 6 6

样例输出

3

1 2 3



算法讨论

注意到1,2,4,8,16,32总是一个可行解,所以答案不会超过6。爆枚答案是什么即可。

事实上字典序最小的通解是1,2,3,6,13,25。

#include <cstdio>
using namespace std;
#define maxn 5656
#define maxlongint 2147483647
int cost[maxn],c[maxn],c1[maxn],t[maxn],f1[maxn];
int b[7]={0,4,8,16,32,64,128};
bool f[maxn];
int n,k,l,maxc,maxk,mindep=maxlongint;
bool flag;

bool check()
{
for (int i=1;i<=n;i++)
if (f1[cost[i]]==0)
return 0;
return 1;
}

int dfs(int dep,int last)
{
if (check() && dep-1<mindep)
{
mindep=dep-1;
for (int i=1;i<=maxk;i++)
c1[i]=c[i];
return 0;
}
if (dep>maxk || dep>mindep)
return 0;
for (int i=last;i<=32;i++)
{
int x=0;
t[++l]=i;
f1[t[l]]++;
for (int j=1;j<l;j++)
{
t[j+l]=t[j]+t[l];
f1[t[j+l]]++;
x++;
}
l+=x;
c[dep]=i;
dfs(dep+1,i);
c[dep]=0;
for (int j=l;j>=l-x;j--)
{
f1[t[j]]--;
t[j]=0;
}
l-=(x+1);
}
}

int main()
{
freopen("driver.in","r",stdin);
freopen("driver.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d",&cost[i]);
if (!f[cost[i]])
{
f[cost[i]]=1;
maxk++;
}
if (maxk>6)
maxk=6;
if (cost[i]>maxc)
maxc=cost[i];
}
dfs(1,1);
printf("%d\n",mindep);
for (int i=1;i<=mindep;i++)
printf("%d ",c1[i]);
fclose(stdin); fclose(stdout);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ 搜索 暴力