蓝桥训练·糖果 状态压缩+dfs

30 篇文章 0 订阅
4 篇文章 0 订阅

糖果店的老板一共有 M

种口味的糖果出售。

为了方便描述,我们将 M
种口味编号 1∼M

小明希望能品尝到所有口味的糖果。

遗憾的是老板并不单独出售糖果,而是 K

颗一包整包出售。

幸好糖果包装上注明了其中 K

颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。

给定 N

包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。
输入格式

第一行包含三个整数 N,M,K

接下来 N
行每行 K 这整数 T1,T2,⋅⋅⋅,TK

,代表一包糖果的口味。
输出格式

一个整数表示答案。

如果小明无法品尝所有口味,输出 −1


数据范围

1≤N≤100
,
1≤M,K≤20,
1≤Ti≤M

输入样例:

6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2

输出样例:

2

二进制枚举,state表示成2进制 其中1就代表该种策略选的类。该做法先预处理下log2【N】,后面要用到。
还要写一个h函数,来估算目前状态下至少需要多少次数才能选完所有类型的糖果。

#include<iostream>
#include<vector>
using namespace std;
const int N=1<<20,M=22;
vector<int>col[M];
int log22[N];
int n,m,k;
int lowbit(int x)
{
    return x&-x;
}
int h(int state)
{
    int res=0;
    for(int i=(1<<m)-1-state;i;i-=lowbit(i))
    {
        int c=log22[lowbit(i)];//代表目前还没被选中
        res++;
        for(auto m:col[c])//算出下界,算出最少需要多少行(不准确值)
        i&=~m;
    }
    return res;
}
bool dfs(int depth,int state)
{
    if(!depth||h(state)>depth)  return state==(1<<m)-1; //看看有没有选满
    int t =-1;
    for(int i=(1<<m)-1-state;i;i-=lowbit(i))
    {
        int c=log22[lowbit(i)];//c代表没选的最后一位
        if(t==-1||col[c].size()<col[t].size())//选择种类最少的方案
           t=c;
    }
    for(auto mm:col[t])
    {
        if(dfs(depth-1,state|mm))
        return true;
    }
    return false;
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    log22[1<<i]=i;
    for(int i=0;i<n;i++)
    {
        int state=0;
        for(int j=0;j<k;j++)
        {
            int c;
            cin>>c;
            state|=1<<c-1;
        }
        for(int j=0;j<m;j++)
        {
            if((state>>j)&1)   col[j].push_back(state); 
        }
    }
    int depth=0;
    while(depth<=m&&!dfs(depth,0))
    depth++;
    if(depth>m) cout<<-1<<endl;
    else cout<<depth<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一份可能的蓝桥杯赛前训练计划: 1. 熟悉考试内容和题型:了解蓝桥杯考试的内容和题型,包括编程语言、数据结构与算法、计算机基础知识和实践能力等方面的内容,并准备相关资料和练习题目。 2. 制定学习计划:根据自己的水平和时间安排,制定一份具体的学习计划,包括每天的学习目标、练习时间和计划完成时间等,以保证充分利用时间进行学习和练习。 3. 提高编程能力:进行编程练习,提高编程能力,特别是数据结构和算法的实践能力。可以参加在线编程竞赛、练习题目和刷题等方式来提高编程能力。 4. 提高计算机基础知识:学习计算机基础知识,包括计算机组成原理、操作系统、计算机网络、数据库等方面的知识,以提高程序的效率和优化能力。 5. 实践能力:进行实践练习,包括操作系统和网络配置、数据库设计和开发、Web开发等方面的实践,以提高实践能力和解决问题的能力。 6. 团队协作:参加团队协作项目,锻炼团队合作和沟通能力,同时学习项目管理和软件开发流程等相关知识。 7. 模拟考试:进行模拟考试,以检验自己的学习成果和考试准备情况,同时找出自己的弱点和不足,加以改进和提高。 8. 调整状态:保持良好的身体状态和心态,保证充足的睡眠和饮食,调整好心态,保持积极向上的心态。 以上是一份可能的蓝桥杯赛前训练计划,具体的训练计划需要根据个人情况和水平来制定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值