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

问题描述
这里写图片描述
输入
这里写图片描述
输出
这里写图片描述
样例输入
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;
}

猜你喜欢

转载自blog.csdn.net/fallen_angel001/article/details/79210797
今日推荐