1243. 糖果

摘要
Title: 1243. 糖果
Tag: 状压dp、重复覆盖问题
Memory Limit: 64 MB
Time Limit: 1000 ms

Powered by:NEFU AB-IN

Link

1243. 糖果

  • 题意

    糖果店的老板一共有 M 种口味的糖果出售。
    为了方便描述,我们将 M 种口味编号 1∼M。
    小明希望能品尝到所有口味的糖果。
    遗憾的是老板并不单独出售糖果,而是 K 颗一包整包出售。
    幸好糖果包装上注明了其中 K 颗糖果的口味,所以小明可以在买之前就知道每包内的糖果口味。
    给定 N 包糖果,请你计算小明最少买几包,就可以品尝到所有口味的糖果。

  • 思路

    重复覆盖问题:最少选几行,使得每一列均至少存在一个1
    解决方法:

    • dancing links
    • 状压dp
    • 爆搜
      • 迭代加深
      • 找选择最少的列
      • 可行性剪枝

    此处为了代码简短和易理解,采用状压dp来做
    1243

    推出了二维式子,但其实发现,对于第一维ii只会用到i1i-1的数据,也就是可以采用优化01背包的策略,将数组优化成一维

  • 代码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    '''
    Author: NEFU AB-IN
    Date: 2022-04-02 14:07:41
    FilePath: \ACM\Acwing\1243.py
    LastEditTime: 2022-04-02 14:14:11
    '''
    N = 110
    INF = int(1e18)
    lst = []
    a = [0] * N
    f = [INF] * (1 << 21)

    n, m, k = map(int, input().split())
    for i in range(n):
    b = list(map(int, input().split()))
    for j in b:
    a[i] |= 1 << (j - 1)

    f[0] = 0
    for i in range(n):
    for j in range(1 << m):
    f[j] = min(f[j], f[j & (~a[i])] + 1)

    if f[(1 << m) - 1] > n:
    print(-1)
    else:
    print(f[(1 << m) - 1])
使用搜索:谷歌必应百度