糖果 | 第十届蓝桥杯省赛C++A组

糖果店的老板一共有 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
题解:

开始使用DFS做,每种糖果包只有选和不选两种情况,结果就TLE了。

因为只有选和不选两种状态,数据量又不是很大,很可能是使用状压DP,(但是可以直接看tag)。

首先是通过位运算,把当前每包的状态列出来。

然后制作一个2^m大小的数组dp记录全部情况达成的最小次数。

遍历这n包糖果的情况,从dp最后一位开始遍历,即m=5情况下,从11111开始遍历。

其中的 j&(~Ni) 语句是列举出原情况包含的所有子情况,比如例题中的1 1 2,写出情况就是0 0 0 1 1(从后往前是1-k),每一位翻转后就是1 1 1 0 0,因为当前只有0 0 0 0 0是有数的,初始为0。则当遍历到情况0 0 0 1 1、0 0 0 0 1、0 0 0 1 0这三种情况时,才会按位或得到0 0 0 0 0,所以才会全部赋值为1,即当只需要1只需要2只需要1和2这三种情况最少抽1包就可以满足。

当然,这道题还可以用 dfs+剪枝+排序优化+去除优化+IDA* 做,但是不如这个简单,(实际上是懒)。

代码:
cpp 复制代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<unordered_set>
#include<unordered_map>
#include<map>
#include<set>
using namespace std;
typedef long long int ll;

/*
6 5 3
1 1 2
1 2 3
1 1 3
2 3 5
5 4 2
5 1 2
*/
#define INF 0x3f3f3f3f

int n,m,k;
int N[101]={0};
int dp[1<<21]={0};

int main(){
    cin >> n >> m >> k;
    for(int i=1;i<=n;i++){
        for(int j=0;j<k;j++){
            int a;
            cin >> a;
            N[i]|=(1<<(a-1));
        }
    }
    memset(dp,INF,sizeof dp);
    dp[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=(1<<m)-1;j>0;j--){
            dp[j]=min(dp[j],dp[j&(~N[i])]+1);
        }
    }
    if(dp[(1<<m)-1]==INF){
        cout << -1 << "\n";
    }
    else{
        cout << dp[(1<<m)-1] <<"\n";
    }
}
相关推荐
程序喵大人2 小时前
【C++进阶】STL算法与函数对象 - 09 函数对象保存状态并复用规则
开发语言·c++·算法·stl·函数对象
致Great7 小时前
DeepSeek Harness插件开发实战教程:我让它自己写了一个 arXiv 搜索插件
算法
ShineWinsu8 小时前
对于C++:auto_ptr、unique_ptr、shared_ptr的模拟实现
c++·面试·笔试·智能指针·unique_ptr·shared_ptr·auto_ptr
XLYcmy10 小时前
京东 算法实习一面 下+手撕
c++·python·llm·概率论·数据处理·训练·codebert
反转180度11 小时前
Qt 6 + C++17 实现 SFTP 批量部署:工业设备运维工具实战解析
运维·c++·qt
罗西的思考11 小时前
【Agent OS / AIOS】AOHP 深度解读:当 OS 开始为 Agent 而设计
人工智能·算法·机器学习
民乐团扒谱机12 小时前
【微实验】组合优化matlab实战(马科维茨投资模型):在收益与风险之间,寻找最优的人生配比
大数据·人工智能·算法·机器学习·数学建模·matlab·组合优化
码匠许师傅12 小时前
【C++ 面试真题】聊聊 C++ 的多继承与虚继承
开发语言·c++·面试
Nil20812 小时前
leetcode 160相交链表
算法·leetcode·链表
迷途之人不知返13 小时前
算法系列2:滑动窗口
算法